It depends what you define as outputs.
in a given module:
var foo = require('foo'), bar = require('bar'), baz = require('baz');
module.exports = function(a, b) {
foo(3);
bar.method(a);
baz(b);
return "done";
}
I have always counted the calls to foo, bar and baz as output that needs to
be tested. This would produce a spec like:
"when calling this module":
"it calls foo with 3"
"it calls bar.method with a"
"it calls baz with b"
"it returns done"
It is just easier to mock bar.method then foo
ie:
var rewire = require('rewire');
var example = rewire('example'); //NOTE: rewire rather then require
example.__set__('foo', jasmine.createSpy());
vrs:
var example = require('example');
var bar = require('bar');
spyOn(bar, "method");
I came across this problem when using one of Isaac's modules (rimraf [1])
where I obviously didn't want to call that in a unit test from my module
but I need to mock it out. Rewire was the only way I could.
[1] - https://github.com/isaacs/rimraf
On Thu, Dec 12, 2013 at 6:37 PM, Brian LeRoux <[email protected]> wrote:
> ALSO: lets avoid using terms like 'I agree' or 'I disagree'. Its
> programming. The answer is ALWAYS 'it depends'. No absolutes in the sea of
> change.
>
>
> On Fri, Dec 13, 2013 at 10:34 AM, Brian LeRoux <[email protected]> wrote:
>
> > Maybe. Have a look at Substack's code and you'll see he has no trouble
> > testing. The reason being he tests interfaces and outputs instead of
> > implementations. That will be another Node 101!
> >
> >
> > On Fri, Dec 13, 2013 at 10:24 AM, Gord Tanner <[email protected]> wrote:
> >
> >> I also agree with this except for returning a function from
> >> module.exports.
> >>
> >> It is possible but makes mocking much much harder for testing.
> >>
> >> think of:
> >>
> >>
> >> var foo = require('foo');
> >>
> >> module.exports = {
> >> awesome: function (a) {
> >> foo(a+1);
> >> }
> >> };
> >>
> >> It is kind of awkward to test this module's use of the foo module. It
> can
> >> be done with rewire [1] but is a little awkward.
> >>
> >> If foo was designed where it exported an object literal with functions
> it
> >> would be much easier to mock:
> >>
> >> var foo = require('foo');
> >>
> >> module.exports = {
> >> awesome: function (a) {
> >> foo.bar(a+1);
> >> }
> >> };
> >>
> >> it("calls foo.bar", function () {
> >> var foo = require('foo');
> >> spyOn(foo, "bar");
> >> });
> >>
> >> Just my 2 cents from a testing perspective.
> >>
> >>
> >> [1] - https://github.com/jhnns/rewire
> >>
> >>
> >> On Thu, Dec 12, 2013 at 6:06 PM, Brian LeRoux <[email protected]> wrote:
> >>
> >> > Create modules that are the smallest possible unit of code. Less code
> is
> >> > fast code. Faster to write. Faster to maintain. Faster to test. On the
> >> > extreme end characters in the Node community such as Substack
> advocate a
> >> > single function per module definition.
> >> >
> >> > module.exports = function() {
> >> > // my logic here
> >> > }
> >> >
> >> > This is kind of extreme and not always possible but a good practice
> >> > nonetheless. The idea is not new. Its a part of the UNIX philosophy:
> "do
> >> > one thing well" coined by Doug Mcilroy. [1]
> >> >
> >> > It can help you make code that looks like this [2] into this [3].
> >> >
> >> >
> >> >
> >> > [1]
> http://homepage.cs.uri.edu/~thenry/resources/unix_art/ch01s06.html
> >> > [2]
> >> >
> >> >
> >>
> https://github.com/apache/cordova-js/blob/c320378b484a172a02d3ee26634bcc584f43b939/Gruntfile.js
> >> > [3] https://github.com/apache/cordova-js/blob/master/Gruntfile.js
> >> >
> >>
> >
> >
>