What is the difference between Jest Mock functions and Sinon spies - javascript

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')

Related

What is the purpose of AngularJS it() and describe() functions?

I have some projects in Javascript/JQuery but AngularJS is a whole new concept to me.
In the docs I have seen the following functions appear alot of time.
describe('PhoneListCtrl', function(){
it('should create "phones" model with 3 phones', function() {
var scope = {},
ctrl = new PhoneListCtrl(scope);
expect(scope.phones.length).toBe(3);
});
});
Are describe() and it() legitimate functions? From the tutorial docs I understand that they are for testing and mock up, but it is still unclear to me how I should run these functions, and if they are merely used as 'foo' and 'bar'.
describe is used to scope tests and it is used to declare them. When the test fails, in your case, you would see a message along the lines of
'should create "phones" model with 3 phones' FAILED!
Followed by some failing assertions. The string provided to it gives context to the assertions.
describe can be used to scope a number of tests to a single topic. Including before and after functions. This is common in lots of testing libraries, not just in javascript. Mocha, Jasmine, but also rspec (from Ruby) use a similar approach.
These are from the Jasmine testing framework. describe defines a test suite, and it defines a "spec" or a test. From the Jasmine documentation:
A test suite begins with a call to the global Jasmine function
describe with two parameters: a string and a function. The string is a
name or title for a spec suite - usually what is under test. The
function is a block of code that implements the suite.
and regarding it:
Specs are defined by calling the global Jasmine function it, which,
like describe takes a string and a function. The string is a title for
this spec and the function is the spec, or test. A spec contains one
or more expectations that test the state of the code under test.
I am not familiar with Angular, but my assumption is that this is perhaps used in the documentation for illustrative purposes in a style similar to that used by the various code koans such as Ruby Koans, where tests are used to illustrate how certain aspects of the language are meant to function. I could be wrong about that last part though.

How can I verify that a method has been called with intern test framework?

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; };.

Unit testing, database approach with JS

I m developping Nodejs (ES6) applications using Mongoose, and I was wondering what could be the aim of unit testing this function :
getAll(){
return MongooseUserShema.find({}).exec();
}
Actually, Mongoose is a well known library, many people use it, and it's well tested.
Wouldn't it be redunbdant if I try to unit test this "facade" ?
I know the importance of testing, but if I don't have any logic inside of my functions, except calls from external libraries (well tested), I was wondering what could be the aim in this case ?
Using Mockito api, create mocks.Use
Mockito.when(<service_call>).thenReturn(<answer>);
and then verify how many times they were called using
Mockito.verify();
Unit testing is important so as to ensure that all external service calls are occuring expected number of times and the functionality with which the method was written is acchieved.
You should not test how Mongoose find() method works. You should write test that confirms its call. I would advice you to stub Mongoose with something like mongoose-mock + proxyquire, and then make an assertion which will verify if find() method was called.

When is spying on method useful during unit testing?

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.

sinon.stub() vs sinon.sandbox.stub()?

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

Categories