testdouble
Advanced tools
Comparing version 1.3.1 to 1.4.0
@@ -9,2 +9,4 @@ # Creating Test Doubles | ||
**Note that `td.func` is available as an alias of `td.function`.** | ||
To create a fake function with test double, we use the `function` function. At its simplest, invoking: | ||
@@ -11,0 +13,0 @@ |
@@ -46,1 +46,42 @@ # Frequently Asked Questions | ||
with quibble / td.js | ||
## Why shouldn't I call both td.when and td.verify for a single interaction with | ||
a test double? | ||
It's a common mistake to call `td.verify` for an invocation that's already been | ||
stubbed with `td.when`. Some users might feel like this is appropriate, | ||
motivated by a desire to be sure that the test double was invoked as expected, | ||
but if the stubbing was necessary to exercise the desired behavior in the | ||
subject, then adding an additional verification is redundant. | ||
For example, given this function: | ||
``` js | ||
function getName(load, id) { | ||
return load(id).name | ||
} | ||
``` | ||
And this test: | ||
``` js | ||
var load = td.function() | ||
td.when(load(42)).thenReturn({name: "Jane"}) | ||
var result = getName(load, 42) | ||
assert(result, "Jane") | ||
td.verify(load(42)) | ||
``` | ||
The assertion that `result` is `"Jane"` is sufficient to specify the behavior | ||
of the function. The additional `td.verify` call is redundant, because if `load` | ||
had not been invoked with `42`, then there's no way that `getName` could have | ||
returned `"Jane"`, since the stubbing wouldn't have been satisfied. Worse, it | ||
further couples the test to the subject's implementation—if, hypothetically, the | ||
`getName` function were able to determine the correct return value without | ||
calling `load`, the test would start failing even though there would | ||
be nothing wrong with the implementation. | ||
As a result, testdouble.js will print a console warning when it detects that | ||
a stubbed invocation is also being verified. |
@@ -19,2 +19,5 @@ // Generated by CoffeeScript 1.10.0 | ||
Then(function() { | ||
return td.func === requireSource('function'); | ||
}); | ||
Then(function() { | ||
return td.object === requireSource('object'); | ||
@@ -21,0 +24,0 @@ }); |
@@ -162,3 +162,3 @@ // Generated by CoffeeScript 1.10.0 | ||
}); | ||
return describe('configuration', function() { | ||
describe('configuration', function() { | ||
describe('ignoring extra arguments (more thoroughly tested via when())', function() { | ||
@@ -280,4 +280,52 @@ When(function() { | ||
}); | ||
return describe('warning when verifying a stubbed invocation', function() { | ||
var afterEach; | ||
Given(function() { | ||
return this.ogWarn = console.warn; | ||
}); | ||
Given(function() { | ||
return this.warnings = []; | ||
}); | ||
Given(function() { | ||
return console.warn = (function(_this) { | ||
return function(msg) { | ||
return _this.warnings.push(msg); | ||
}; | ||
})(this); | ||
}); | ||
afterEach = console.warn = this.ogWarn; | ||
Given(function() { | ||
return this.td = td["function"]('.foo'); | ||
}); | ||
context('an exact match in calls', function() { | ||
Given(function() { | ||
return td.when(this.td(1)).thenReturn(5); | ||
}); | ||
Given(function() { | ||
return this.td(1); | ||
}); | ||
When(function() { | ||
return td.verify(this.td(1)); | ||
}); | ||
return Then(function() { | ||
return this.warnings[0] === "Warning: testdouble.js - td.verify - test double `.foo` was both stubbed and verified with arguments (1), which is redundant and probably unnecessary. (see: https://github.com/testdouble/testdouble.js/blob/master/docs/B-frequently-asked-questions.md#why-shouldnt-i-call-both-tdwhen-and-tdverify-for-a-single-interaction-with )"; | ||
}); | ||
}); | ||
return context('matchers are used', function() { | ||
Given(function() { | ||
return td.when(this.td(td.matchers.isA(Number))).thenReturn(5); | ||
}); | ||
Given(function() { | ||
return this.td(1); | ||
}); | ||
When(function() { | ||
return td.verify(this.td(1)); | ||
}); | ||
return Then(function() { | ||
return this.warnings.length === 0; | ||
}); | ||
}); | ||
}); | ||
}); | ||
}).call(this); |
@@ -11,3 +11,7 @@ // Generated by CoffeeScript 1.10.0 | ||
} | ||
return equalsWithMatchers(expectedArgs, actualArgs); | ||
if ((config != null ? config.allowMatchers : void 0) !== false) { | ||
return equalsWithMatchers(expectedArgs, actualArgs); | ||
} else { | ||
return _.eq(expectedArgs, actualArgs); | ||
} | ||
}; | ||
@@ -14,0 +18,0 @@ |
@@ -5,2 +5,3 @@ // Generated by CoffeeScript 1.10.0 | ||
"function": require('./function'), | ||
func: require('./function'), | ||
object: require('./object'), | ||
@@ -7,0 +8,0 @@ when: require('./when'), |
// Generated by CoffeeScript 1.10.0 | ||
(function() { | ||
var _, callsStore, invocationSummary, log, store, stringifyArgs, stringifyName, timesMessage, unsatisfiedErrorMessage; | ||
var _, argsMatch, callsStore, invocationSummary, log, store, stringifyArgs, stringifyName, stubbingsStore, timesMessage, unsatisfiedErrorMessage, warnIfStubbed; | ||
@@ -11,2 +11,4 @@ _ = require('lodash'); | ||
stubbingsStore = require('./store/stubbings'); | ||
stringifyArgs = require('./stringify/arguments'); | ||
@@ -16,2 +18,4 @@ | ||
argsMatch = require('./args-match'); | ||
module.exports = function(__userDoesPretendInvocationHere__, config) { | ||
@@ -24,3 +28,3 @@ var last; | ||
if (callsStore.wasInvoked(last.testDouble, last.args, config)) { | ||
return warnIfStubbed(last.testDouble, last.args); | ||
} else { | ||
@@ -34,2 +38,13 @@ return log.fail(unsatisfiedErrorMessage(last.testDouble, last.args, config)); | ||
warnIfStubbed = function(testDouble, actualArgs) { | ||
return _.find(stubbingsStore["for"](testDouble), function(stubbing) { | ||
if (argsMatch(stubbing.args, actualArgs, { | ||
allowMatchers: false | ||
})) { | ||
log.warn('td.verify', "test double" + (stringifyName(testDouble)) + " was both stubbed and verified with arguments (" + (stringifyArgs(actualArgs)) + "), which is redundant and probably unnecessary.", "https://github.com/testdouble/testdouble.js/blob/master/docs/B-frequently-asked-questions.md#why-shouldnt-i-call-both-tdwhen-and-tdverify-for-a-single-interaction-with"); | ||
return true; | ||
} | ||
}); | ||
}; | ||
unsatisfiedErrorMessage = function(testDouble, args, config) { | ||
@@ -39,2 +54,11 @@ return ("Unsatisfied verification on test double" + (stringifyName(testDouble)) + ".\n\n Wanted:\n - called with `(" + (stringifyArgs(args)) + ")`" + (timesMessage(config)) + ".") + invocationSummary(testDouble); | ||
stringifyName = function(testDouble) { | ||
var name; | ||
if (name = store["for"](testDouble).name) { | ||
return " `" + name + "`"; | ||
} else { | ||
return ""; | ||
} | ||
}; | ||
invocationSummary = function(testDouble) { | ||
@@ -52,11 +76,2 @@ var calls; | ||
stringifyName = function(testDouble) { | ||
var name; | ||
if (name = store["for"](testDouble).name) { | ||
return " `" + name + "`"; | ||
} else { | ||
return ""; | ||
} | ||
}; | ||
timesMessage = function(config) { | ||
@@ -63,0 +78,0 @@ if (config.times == null) { |
// Generated by CoffeeScript 1.10.0 | ||
(function() { | ||
module.exports = '1.3.1'; | ||
module.exports = '1.4.0'; | ||
}).call(this); |
{ | ||
"name": "testdouble", | ||
"version": "1.3.1", | ||
"version": "1.4.0", | ||
"description": "A minimal test double library for TDD with JavaScript", | ||
@@ -5,0 +5,0 @@ "homepage": "https://github.com/testdouble/testdouble.js", |
@@ -126,2 +126,3 @@ # testdouble.js | ||
1. [Why doesn't `td.replace()` work with external CommonJS modules?](docs/B-frequently-asked-questions.md#why-doesnt-tdreplace-work-with-external-commonjs-modules) | ||
12. [Configuration](docs/C-configuration.md) | ||
1. [td.config](docs/C-configuration.md#tdconfig) |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
758884
158
17394
128