Reputation: 851
In a mocha/chai setup, I'm trying to use babel-plugin-rewire in conjunction with sinon for testing and stubbing functions within the same module. These are the example files below:
Firstly, an index.js and test file that uses both sinon and babel-plugin-rewire. Rewiring works, but for some reason, my stubs don't work. The function it is applied to is never stubbed and only the original value is returned:
// index.js
function foo() {
return "foo";
}
export function bar() {
return foo();
}
export function jar() {
return "jar";
}
//index.test.js
import chai from "chai";
import sinon from "sinon";
import * as index from "./index";
const expect = chai.expect;
const sandbox = sinon.sandbox.create();
describe("babel-plugin-rewire", () => {
it("should be able to rewire", () => {
index.default.__set__("foo", () => {
return "rewired"; // successfullly rewires
});
expect(index.bar()).to.equal("rewired"); // works fine
index.default.__ResetDependency__("foo");
expect(index.bar()).to.equal("bar"); // works fine
});
});
describe("sinon", () => {
afterEach(() => {
sandbox.restore();
});
it("should call the original jar", () => {
expect(index.jar()).to.equal("jar"); // works fine
});
it("should call the stubbed jar", () => {
sandbox.stub(index, "jar").returns("stub");
expect(index.jar()).to.equal("stub"); // fails
});
});
And here is two example files solely using sinon stubs. The same thing happens:
// stub.js
export function stub() {
return "stub me";
}
// stub.test.js
import * as stub from "./stub";
import sinon from "sinon";
import chai from "chai";
const expect = chai.expect;
const sandbox = sinon.createSandbox();
const text = "I have been stubbed";
describe("sinon stubs", () => {
afterEach(() => {
sandbox.restore();
});
it("should stub", () => {
sandbox.stub(stub, "stub").returns(text);
expect(stub.stub()).to.equal(text); // fails
});
});
And this here is the babelrc that is being used for mocha
{
"presets": [
"@babel/preset-env"
],
"plugins": [
"rewire"
]
}
If I remove rewire from the plugins, the problem goes away. Though obviously this means I can't use rewire, which as I mentioned earlier I need in order to stub functions within the same dependency. Is this a bug with the module or am I missing something here?
Upvotes: 3
Views: 1450
Reputation: 654
I had the same problem with one of my tests. There was an action that after signing out the user, triggered a page redirect. The redirect itself was implemented in separate file.
import * as utils from '../utils.js';
import sinon from 'sinon';
it('will dispatch an action and redirect the user when singing out', () => {
const redirectStub = sinon.stub(utils, 'redirect').returns(true);
// dispatch and assertion of action omitted
expect(redirectStub.calledOnce).toBeTruthy();
redirectStub.restore();
});
Then, for various reasons, I had to add babel-rewire-plugin
to my tests. This, broke that specific test above. The calledOnce
or any other sinon methods were always returning false
.
Unfortunately, I wasn't able to make the spying/stubbing work anymore. I had to rewrite my test like this:
import { __RewireAPI__ } from '../utils.js';
import sinon from 'sinon';
it('will dispatch an action and redirect the user when singing out', () => {
__RewireAPI__.__Rewire__('redirect', () => true);
// dispatch and assertion of action omitted
__RewireAPI__.ResetDependencty('redirect');
});
As you can see, there are no spies or stubs assertions anymore. I rewired the redirect
method and then reset it.
There is a babel-plugin-rewire-exports
library however, that seems to allow you to both rewire and spy/stub. I haven't tried it myself, but it can be an option if you don't want to rewrite your tests. Here is the link.
Upvotes: 2