intern icon indicating copy to clipboard operation
intern copied to clipboard

Include a default mock/stub library

Open bitpshr opened this issue 11 years ago • 34 comments

It can be tedious work with stubbed / mocked functions. Jasmine and others include a spy implementation to make this easier. Chai has a separate plugin for this at https://github.com/chaijs/chai-spies. Rather than making the user pull in this plugin manually, it may be nice to have Intern wrap it, perhaps as a loader plugin similar to the assertion interfaces.

bitpshr avatar Jun 11 '13 18:06 bitpshr

+1 for built-in spy library

manoharank avatar Jun 20 '13 05:06 manoharank

If we are going to include something to do this, I’d prefer it to not be something that says “you are probably going to want something more robust” in its readme.

csnover avatar Jun 26 '13 03:06 csnover

A more robust library could be sinon.js in conjunction with sinon-chai which provides assertions for chai based on sinon.js.

I've already used it in the past and it integrates very well with chai.

Bjornej avatar Jul 04 '13 07:07 Bjornej

+1 for sinon however we ran into issues with xhr2 when dojo 1.8 was released, though the maintainer seemed to be amenable to accepting patches, it looks like more changes have been made recently so it may work now

lbod avatar Aug 05 '13 13:08 lbod

Mocking (and other) libraries come and go. It'd be nice not to be forced to use any one particular type of mock library. Currently we use Sinon (with a tiny workaroudn for XHR2), pulled in via require, but right now there's nothing stopping us moving to another library, or migrating piece-by-piece as we like.

RoystonS avatar Aug 05 '13 14:08 RoystonS

@csnover is there any update on this and have you any thoughts whether support for stubbing/mocking libraries is likely to be included in future?

lbod avatar Oct 24 '13 18:10 lbod

No, there is no update. I have no new thoughts on whether or not this is likely to be included in the future.

csnover avatar Oct 24 '13 18:10 csnover

Ok thanks, you should probably mark this enhancement as invalid then. At least it lets others know.

Also I suggest you update the comparison table on the README to include this, other libraries like Buster and Jasmine support stubs/mocks & spies

lbod avatar Oct 24 '13 18:10 lbod

It’s not invalid, it’s just not done yet. My thoughts are unchanged.

csnover avatar Oct 24 '13 19:10 csnover

chai-spies is really slim in features and didn't work for many use cases I had. I submitted a PR to Sinon.JS to add AMD (since it was never suggested before).

phated avatar Nov 18 '13 06:11 phated

SinonJS accepted my PR for AMD support https://github.com/cjohansen/Sinon.JS/commit/7bf869e435b728e7c4a64ea845daa0db5ee89dd2

phated avatar Nov 23 '13 02:11 phated

+1 for including sinon.js as a built-in for intern

devangnegandhi avatar Apr 10 '14 03:04 devangnegandhi

The problem I've had with Sinon's AMD support is that it only really works in the built version, so you have to configure the loader to point to sinon/pkg/sinon. As long as we're using a version from npm, this probably won't be a problem, but it makes the package config a bit goofy.

bryanforbes avatar Apr 10 '14 14:04 bryanforbes

Do you guys have any documentation or example on how to use chai-spies or sinon.js with intern.js? thank you!

yagoferrer avatar Jun 02 '14 21:06 yagoferrer

I have an example project at https://github.com/jason0x43/intern-mocking-example that gives a couple basic examples using the sinon branch in intern. Both the branch and the example are still a work in progress, though.

jason0x43 avatar Jun 02 '14 21:06 jason0x43

Thank you Jason! That's so cool! I'lll use your branch for my tests.

yagoferrer avatar Jun 03 '14 16:06 yagoferrer

@csnover: How are people currently getting spy/mock functionality in intern without something like this? Seems like such a basic requirement for a testing framework that I'm surprised that intern has come this far without it. Am I missing something?

stdavis avatar Sep 29 '14 15:09 stdavis

sinon now sometimes works properly without the built version, but I regularly have failures. It frustrated me so much I started kitsonk/sutabu. It does basic stubbing and spying. It isn't fully compatible with sinon (nor was it intended to be). Hopefully it can inspire some stuff for The Intern.

kitsonk avatar Sep 29 '14 16:09 kitsonk

@stdavis stubbing and mocking is independent of running tests. that's not to say that intern couldn't include something but it explains how it's quite easy to get by without this functionality being in intern.

i use sinon in my tests but i've learned which parts not to use with AMD... one big hint with AMD is only use spies and stubs but not stub behaviors

i put a few days effort into bringing sinon into better shape for working via AMD and it should be usable from master of sinon. waiting for a new release and hoping it doesn't get accidentally broken but wouldn't be surprised if it does get broken since i don't have the bandwidth to watch the codebase like a hawk.

neonstalwart avatar Sep 29 '14 17:09 neonstalwart

@neonstalwart Just out of curiosity, what kinds of issues do stub behaviors cause with AMD?

jason0x43 avatar Sep 30 '14 00:09 jason0x43

@jason0x43 due to the way sinon/lib/sinon.js loads AMD dependencies in parallel there are potential race conditions. an example is that sinon.behavior may not be defined by the time this block of code is executed - https://github.com/cjohansen/Sinon.JS/blob/v1.10.3/lib/sinon/stub.js#L135-149

this issue usually reveals itself when you have something like sinon.stub().returns(...) and an error is thrown indicating that there is no returns method.

the general fix for this was to rewrite all the sinon modules to explicitly declare the other modules they depend on, create a method that defines the API of that module so that it can be called at a time which is appropriate for the way in which the code is being loaded, and finally, some code was extracted into a new module in order to break circular dependencies that existed in just about every module - they depended on sinon/lib/sinon.js for utility code defined there and sinon/lib/sinon.js depended on each of the other modules in order to generate the full sinon.* exported from sinon/lib/sinon.js

neonstalwart avatar Sep 30 '14 02:09 neonstalwart

I should also point out that a built version of sinon, which would have all the dependencies available synchronously, has its own issues. in order to bundle 2 AMD libs as part of the distribution the build script creates a dummy define that is within scope of the source of those bundled external dependencies. unfortunately, it is also within scope of all the sinon modules which means that if you try to load the built distribution of sinon, the real AMD define is never called and so you can't get a reference to sinon as an AMD dependency - you need to reference the global instead.

the whole thing was a huge mess. @stdavis I think the question for me is how did sinon ever come so far in such a state :stuck_out_tongue_winking_eye:

neonstalwart avatar Sep 30 '14 03:09 neonstalwart

Ah, that. I've been using intern's order module to load all the pieces, which has worked well enough in my limited testing.

jason0x43 avatar Sep 30 '14 04:09 jason0x43

I've been using intern's order module to load all the pieces

i've been doing a similar thing for a quite a while too.

neonstalwart avatar Sep 30 '14 16:09 neonstalwart

Just using intern!order didn't work so well after some slightly more complex tests, and I ran into the race condition mentioned by @neonstalwart. The most recent commit gets around that problem by using a loader map to mock sinon's dependencies when the main sinon module is loaded.

jason0x43 avatar Oct 27 '14 01:10 jason0x43

@jason0x43 have you tried to use sinon from master? apparently there should be a new release soon and i'd like to know if you've found anything broken. it would be best to address all the issues within sinon if possible.

neonstalwart avatar Oct 27 '14 12:10 neonstalwart

We've actually found integrating Sinon with Intern to be very straightforward, and have been happily using the two together since June 2013 without any problems, using the standard 'built' Sinon distribution. We've a crazy-simple top-level sinon.js module, which works around Sinon's current AMD support:

define(["./sinon-dist/sinon.js"], function() {
    return sinon;
});

Tests that want Sinon simply pull that module in and use the resulting module value. If Sinon is changed so that it's more AMD-friendly later, we'll replace our module with a reference to that directly.

We used to have some nasty code that helped Sinon work with the XHR2 mechanism in Dojo, but they now work together out of the box. We also used to remove the global sinon variable, but we now leave it in place so that sinon-chai works.

Integrating sinon-chai used to be slightly tricky in Intern, but when Intern exposed some more bits of chai, that's straightforward too:

define(["intern/chai!", "third_party/sinon-chai/lib/sinon-chai"], function (chai, sinonChai) {
        chai.use(sinonChai);
        // Other bits: we also integrate Chai-as-promised and our own chai helpers too...
});

We're currently on Sinon 1.10.3, Intern 2.1.1 and Sinon-Chai 2.5.0. (We can't use Sinon-Chai 2.6.0 as it doesn't play nicely with Chai 1.9.1 from Intern.)

Hope this helps somebody: the integration of the existing public releases of Sinon and Intern doesn't have to be difficult.

RoystonS avatar Oct 27 '14 12:10 RoystonS

@neonstalwart It looks like 1.11.0 includes some improved AMD support (is there more in master?). I'll try it out. I was going for a stable interim solution since getting upstream changes into libraries can take a while, but it would certainly be ideal if sinon has already take care of the issue.

jason0x43 avatar Oct 27 '14 15:10 jason0x43

@jason0x43 1.11.0 was released very shortly after i left my previous comment - so 1.11.x has everything that i was talking about in master.

neonstalwart avatar Oct 28 '14 14:10 neonstalwart

Has anyone taken a look at testdouble.js? It's got some commercial backing....

indolering avatar Nov 18 '16 21:11 indolering