Using sinon and sinon-qunit in our front end unit tests, and I'm struggling to understand the difference in these methods. We are using sinon.sandbox.stub() (literally that is the function, we do not create a sandbox) and these stubs are apparently restored after each test automatically. I just don't see this anywhere in the documentation.
I wouldn't think that this method exists, I would think you would need to explicitly create a sandbox using sinon.sandbox.create(). On that sandbox object you would call the stub function, i.e. mySandbox.stub(), not "sinon.sandbox.stub()".
Could anyone help me understand?
Stubs - Sinon.JS
sinon.stub(); read about from here
Sandboxes - Sinon.JS
sandbox.stub(); read detail from here
Works almost exactly like sinon.stub, only also adds the returned stub to the internal collection of fakes for easy restoring through sandbox.restore().
The sandbox stub method can also be used to stub any kind of property. This is useful if you need to override an object’s property for the duration of a test, and have it restored when the test completes
Related
I've started using Sinon.js to mock a MongoDB library in a Mocha test suite. I'm confused as to why mock.restore() in my afterEach blocks do not actually clear out the mocks & assertions I've set up in other tests. Example:
mockedMongo.expects('updateCustomer').once();
mockedMongo.restore();
mockedMongo.expects('updateCustomer').never();
mockedMongo.verify(); // error here
The last line will throw an Expected updateCustomer([...]) once (never called) ExpectationError. In the documentation it says that mock.restore() "Restores all mocked methods". I'm trying to figure out what that actually means, since it doesn't clear out my previous expectation, even when it seems that I've overwritten the mock on that method with something else. Thoughts?
Summary
If any methods have been wrapped in a proxy by the mock, restore() returns them to their original state. That's all it does.
Details
Looking at the source gives the following info:
calling expects() sets up a proxy for the method if no expectations have been set on it yet, and then adds an expectation
calling verify() cycles the expectations on the proxies and verifies each, then calls restore()
restore() cycles the proxies and restores the original methods
All restore() does is remove any proxies added by expects(), it doesn't affect the expectations stored by the mock.
So for each line in your example code:
create proxy for updateCustomer and add expectation of once
restore original updateCustomer
add expectation of never to updateCustomer
cycle the two expectations on updateCustomer and record that once fails, call restore(), then report that once failed
I am mocking a function with Jest and the documentation says they are really 'spies'. I have also seen the use of spies in SinonJS but I could find no clear difference between the two. If they are serving the same purpose, is there any reason to choose one over the other?
Jest Mock Functions
SinonJS
The main behaviour of both is the same, they are functions that can remember their calls. So for both you can figure out how often they were called and with which arguments. Sinon has a much wider API for what you can test on spies, and it has an API to replace functions in objects with spies.
I have found a caveat when using Sinon Vs Jest.
In my case I wanted to mock a whole module and check if this was being called from the main function I was testing:
parent func(){ // The func my test was about
childFunc() // The call I tried to mock and check if it was called.
...
, I tried using Sinon.spy(module, 'default') But kept throwing errors saying couldn't find 'default'.
Seems stub, spy, and mock are all good when you want to mock results for function or you have functional properties. In my case switching to jest was super simple and achieved what I needed by just using
jest.mock('./module')
I'm using The Intern test framework for testing my web application. Now I need to verify that a method has been invoced during a test, but I cannot find any resource which describes that this is possible with e.g. chai!assert or bdd. Can you give me a hint how I can accomplish a verification of a method invocation during test?
There isn't a standard built-in way to do this, but there are several ways to go about it. As #artem suggested, sinon works with Intern and has the ability to stub out methods on objects. If you're testing Dojo code, you can use dojo/aspect to add aspect advice to a method and use that to record that the method was called. You can also just use the plain JavaScript technique of replacing the function of interest with a stub, like var called = false; someObject.myMethod = function () { called = true; };.
When writing tests for Backbone/Marionette Views I have noticed that at times, when using setElement in the render or onRender (if a marionette itemView), I cannot later trigger a specific event (i.e click) on an element set in the view's events hash, from my tests.
However when doing element.dispatchEvent('createdEvent') in the test suit, no error is reported, but the method I am spying on with sinon is never called.
If I simply stub the setElement method it returns an error: TypeError: 'undefined' is not an object (evaluating 'this.$el.attr').
I am guessing I need some more setting-up to do in my tests apart from simply instantiating the view and necessarymodelsandcollectionsalong with anyspies,stubs, orfakeServers, or either refactoring the existingviewsand removing thesetElement` method?
Has anyone come across a similar situation before?
How do I get around this?
I am using mocha, chai, sinon and phantomjs for my tests.
I have a more detailed SO question, with a working example, on this topic here: https://stackoverflow.com/questions/33828501/marionette-itemview-click-event-not-firing-when-triggered-from-tests
With Jasmine it is possible to spyOn methods, but I'm not clear on when would it be actually useful. My understanding is that unit tests should not be concerned with implementation details and testing if method is called would be implementation detail.
One place I might think of is spying on scope.$broadcast (Angular) etc but then again this would be implementation detail and not sure if unit tests should even bother with how the code works, as long as it gives expected result.
Obviously there are good reasons to use spyOn so what would be good place to use it?
The spyOn you describe is more commonly known in testing as a MOCK, although to be more clear it allows for 2 operations:
Create a new implementation for a method via createSpy (this is the classical mock)
Instrument an existing method via spyOn (this allows you to see if the method was called and with what args, the return value etc.)
Mocking in probably the most used technique in unit testing. When you are testing a unit of code, you'll often find that there are dependencies to other units of code, and those dependencies have their own dependencies etc. If you try to test everything you'll end up with an module / UI test, which are expensive and difficult to maintain (they are still valuable, but you want as few of those as possible)
This is where mocking comes in. Imagine your unit calls to a REST service for some data. You don't want to take a dependency on a service in your unit test. So you mock the method that calls the service and you provide your own implementation that simply returns some data. Want to check that your unit handles REST errors? Have your mock return an error. etc.
It can sometimes be useful to know if your code actually calls another unit of code - imagine that you want to make sure your code correctly calls a logging module. Just mock (spyOn) that logging module and assert that it was called X number of times with the proper parameters.
You can spy functions and then you will be able to assert a couple of things
about it. You can check if it was called, what parameters it had, if it
returned something or even how many times it was called!
Spies are highly useful when writing tests, so I am going to explain how to
use the most common of them here.
// This is our SUT (Subject under test)
function Post(rest) {
this.rest = rest;
rest.init();
}
We have here our SUT which is a Post constructor. It uses a RestService to
fetch its stuff. Our Post will delegate all the Rest work to the RestService
which will be initialized when we create a new Post object. Let’s start testing
it step by step:
`describe('Posts', function() {
var rest, post;
beforeEach(function() {
rest = new RestService();
post = new Post(rest);
});
});`
Nothing new here. Since we are going to need both instances in every test,
we put the initialization on a beforeEach so we will have a new instance every
time.
Upon Post creation, we initialize the RestService. We want to test that, how
can we do that?:
`it('will initialize the rest service upon creation', function() {
spyOn(rest, 'init');
post = new Post(rest);
expect(rest.init).toHaveBeenCalled();
});`
We want to make sure that init on rest is being called when we create a new
Post object. For that we use the jasmine spyOn function. The first parameter is
the object we want to put the spy and the second parameter is a string which
represent the function to spy. In this case we want to spy the function init
on the spy object. Then we just need to create a new Post object that will call
that init function. The final part is to assert that rest.init have been
called. Easy right? Something important here is that the when you spy a
function, the real function is never called. So here rest.init doesn’t actually
run.