Permalink
Browse files

there is now a mock_function macro for mocking on anonymous functions

  • Loading branch information...
andykent committed May 19, 2009
1 parent 3ce4836 commit 6cf673edcf591f2434a7110f65bd3c05c2c3d33e
Showing with 66 additions and 4 deletions.
  1. +18 −4 lib/smoke.mock.js
  2. +4 −0 plugins/screw.mocking.js
  3. +44 −0 spec/mock_spec.js
View
@@ -26,7 +26,8 @@ Smoke.Mock = function(originalObj) {
obj._expectations = {};
obj.stub = function(attr){
return new Smoke.Stub(this, attr);
- },
+ };
+
obj.should_receive = function(attr){
var expectation = new Smoke.Mock.Expectation(this, attr);
if(this._expectations[attr]==undefined) this._expectations[attr] = [];
@@ -39,17 +40,30 @@ Smoke.Mock = function(originalObj) {
return previousFunction!=undefined ? previousFunction.apply(mock,arguments) : undefined;
};
return expectation;
- },
+ };
+
obj.checkExpectations = function(){
for(var e in this._expectations) {
var expectations = this._expectations[e]
for(var i=0; i < expectations.length; i++) expectations[i].check();
};
- },
+ };
+
Smoke.mocks.push(obj);
return obj;
};
+Smoke.MockFunction = function(originalFunction, name) {
+ var name = name || 'anonymous_function';
+ var originalFunction = originalFunction || function() {};
+ var scope = function() { return scope.mockFunction.apply(this,arguments) };
+ scope[name] = originalFunction;
+ scope.mockFunction = function() { return scope[name].apply(this,arguments); };
+ var mock = Smoke.Mock(scope);
+ mock.should_be_invoked = function() { return mock.should_receive(name) };
+ return mock;
+};
+
Smoke.Mock.Expectation = function(mock, attr) {
this._mock = mock;
this._attr = attr;
@@ -84,7 +98,7 @@ Smoke.Mock.Expectation.prototype = {
};
},
and_return: function(v){
- this.returnValue = v
+ this.returnValue = v;
},
check: function(){
if(this.exactCount!=undefined) this.checkExactCount();
View
@@ -5,6 +5,10 @@ Screw.Matchers.mock = function(m) {
return Smoke.Mock(m);
};
+Screw.Matchers.mock_function = function(func,name) {
+ return Smoke.MockFunction(func,name);
+};
+
Screw.Matchers.stub = function(obj, attr) {
return new Smoke.Stub(obj,attr);
};
View
@@ -129,6 +129,50 @@ Screw.Unit(function() {
});
});
+ describe("anonymous functions", function() {
+ before(function() {
+ foo = function() { return 'bar' };
+ mockObj = mock_function(foo);
+ });
+
+ it("should leave the original intact", function() {
+ expect(foo()).to(equal,'bar');
+ });
+
+ it("should still execute the mock like the original", function() {
+ expect(mockObj()).to(equal,'bar');
+ });
+
+ it("should still execute the mock like the original with arguments", function() {
+ var a = function(x,y,z) { return x+y+z };
+ aMock = mock_function(a)
+ expect(aMock('a','b','c')).to(equal,'abc');
+ });
+
+ it("should allow expectations to be set as usual", function() {
+ mockObj.should_receive('baz').exactly('once').and_return(1);
+ mockObj.baz()
+ });
+
+ it("should allow expectations to be set on invocations of itself", function() {
+ mockObj.should_be_invoked();
+ mockObj();
+ });
+
+ it("should allow expectation rules to be set", function() {
+ mockObj.should_be_invoked().exactly('twice').with_arguments('a');
+ mockObj('a');
+ mockObj('a');
+ });
+
+ it("should not call the original if a return value is specified", function() {
+ var func = function() { throw("I should not be called") };
+ var mockFunc = mock_function(func);
+ mockFunc.should_be_invoked().and_return('hello');
+ expect(mockFunc()).to(equal, 'hello');
+ });
+ });
+
describe("when array has been monkey-patched by js library not to be named here (grrr)", function() {
before(function() {
Array.prototype.remove = function() {

0 comments on commit 6cf673e

Please sign in to comment.