Suppose I have two functions, foo
is called inside a bar
. I have a Meteor app, so I decided to use meteor mocha
package along with sinon
and chai
and not jest
// foo.js
const foo = () => // call to a google maps api;
export default foo;
// bar.js
const bar = (x) => {
foo();
...
};
export default bar;
What is the correct approach of mocking foo
in this case
Currently I've came up with the following solution:
import foo from 'path/to/foo.js'
import bar from 'path/to/bar.js'
describe('my test suite', function() {
it('should pass the test', function() {
foo = spy();
bar(5);
assert(foo.calledOnce);
});
});
The following code works, but is that correct to redefine foo
?
UPDATE
Also, it's not possible to create a mock or stub this way, which makes me think that Sinon is not suitable for mocking standalone functions
Stubbing functions in a deeply nested object getElementsByTagName as an example above. How can you stub that? The answer is surprisingly simple: var getElsStub = sinon.
var sinon = require('sinon'); var start_end = require('./start_end'); describe("start_end", function(){ before(function () { cb_spy = sinon. spy(); }); afterEach(function () { cb_spy. reset(); }); it("start_pool()", function(done){ // how to make timer variable < 1, so that if(timer < 1) will meet start_end.
Mocks allow you to create a fake function that passes or fails depending on your needs. You can ensure it was called with certain arguments, or check how many times it was called. You must call mock() on an object.
You could use rewire js it is a library that lets you inject mocked properties into your module you want to test. Your require statement would look something like this: var rewire = require("rewire"); var sqsOutputResultSender = rewire('../utility/sqsThing');
If you’ve heard the term “mock object”, this is the same thing — Sinon’s mocks can be used to replace whole objects and alter their behavior similar to stubbing functions. They are primarily useful if you need to stub more than one function from a single object. If you only need to replace a single function, a stub is easier to use.
Also, it's not possible to create a mock or stub this way, which makes me think that Sinon is not suitable for mocking standalone functions Sinon works well on standalone JavaScript functions. Here is an example of how to wrap the default export of a module in a Sinon spy:
Use a stub instead. In general you should have no more than one mock (possibly with several expectations) in a single test. Expectations implement both the spies and stubs APIs. To see what mocks look like in Sinon.JS, here is one of the PubSubJS tests again, this time using a method as callback and using mocks to verify its behavior
In such cases, you can use Sinon to stub a function. Let’s see it in action. Start by installing a sinon into the project. Once installed you need to require it in the app.js file and write a stub for the lib.js module’s method. Here is how it looks :
Sinon
works well on standalone JavaScript functions.
Here is an example of how to wrap the default export of a module in a Sinon
spy:
import * as sinon from 'sinon';
import * as fooModule from 'path/to/foo.js'
import bar from 'path/to/bar.js'
describe('my test suite', function() {
it('should pass the test', function() {
const spy = sinon.spy(fooModule, 'default'); // wrap the function in a spy
bar(5);
assert(spy.calledOnce); // SUCCESS
spy.restore(); // restore the original function
});
});
Here is an example of how to replace the default export of a module with a Sinon
stub:
import * as sinon from 'sinon';
import * as fooModule from 'path/to/foo.js'
import bar from 'path/to/bar.js'
describe('my test suite', function() {
it('should pass the test', function() {
const stub = sinon.stub(fooModule, 'default').returns('something else'); // stub the function
bar(5); // foo() returns 'something else' within bar(5)
assert(stub.calledOnce); // SUCCESS
stub.restore(); // restore the original function
});
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With