I'm writing a Mock object factory and need it to inject some sort of destructor method to work nicely.
At the moment you can provide expectOnce() type assertions on the Mock but the problem is that they will try to run at the time you call them rather than later so you need to call expectOnce() *after* any operations were done on the mock. If I could have it just set something up and then check once the object destructs it would allow the call to be made anywhere. Unless there's perhaps a better way than my current approach?
Here's how it works at the moment:
Code: Select all
function interfaceToMock()
{
this.someMethod = function() {}
this.anotherMethod = function() {}
}
Code: Select all
function myTestCase()
{
this.testMockRunsACertainMethod = function()
{
var mockfactory = new Mock(new interfaceToMock());
var myMock = mockfactory.generate('myMockName');
myMock.setReturnValue('someMethod', 42);
this.assertEqual(42, myMock.someMethod());
myMock.expectOnce('someMethod'); //Works because we ran it earlier
}
}
myTestCase.prototype = new UnitTestCase();
myTestCase.run(new DefaultRunner());
Code: Select all
function Mock(theClass)
{
this.generate = function(name, testcase)
{
var mockObj = new Object();
mockObj._retvals = new Array();
mockObj._calls = new Array();
mockObj._testcase = testcase;
mockObj.setReturnValue = function(f, v)
{
mockObj._retvals[f] = v;
}
mockObj.expectOnce = function(f)
{
if (mockObj._calls[f] != 1)
{
throw new JSTesterException('Mock expectOnce assertion failed with count ' + mockObj._calls[f]);
}
else
{
mockObj._testcase.pass('Mock expectOnce passed, OK');
}
}
for (var _x in theClass)
{
if (typeof theClass[_x] == 'function')
{
mockObj._retvals[_x] = null;
mockObj._calls[_x] = 0;
mockObj[_x] = function()
{
if (Mock.isGenerated(name, _x))
{
mockObj._calls[_x]++;
return mockObj._retvals[_x];
}
else
{
Mock.setGenerated(name, _x);
}
}
}
}
return mockObj;
}
}
Mock._completelyGenerated = new Array();
Mock.setGenerated = function(n, f)
{
if (typeof this._completelyGenerated[n] == 'undefined')
{
this._completelyGenerated[n] = new Array();
}
this._completelyGenerated[n][f] = true;
}
Mock.isGenerated = function(n, f)
{
if (typeof this._completelyGenerated[n] == 'undefined') return false;
else
{
if (typeof this._completelyGenerated[n][f] != 'undefined') return true;
}
}