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 <b...@brian.io> 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 <b...@brian.io> 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 <gtan...@gmail.com> 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 <b...@brian.io> 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
> >> >
> >>
> >
> >
>

Reply via email to