Mocking multiple modules in single jest test - module

I am facing an issue in jest mocking. I can mock 1 module per test file but I am unable to mock multiple modules for single jest test.
E.x.
import mock1 from '../mockClass1';
import mock2 from '../mockClass2';
jest.mock('../mockClass1');
jest.mock('../mockClass2');
mock1.mockImplementation(() => {});
mock2.mockImplementation(() => {});
But this gives error as 1 of the mocks is not working. Is there a way of mocking both modules as I need them both in snapshot test of my class.

Use another mock-method. I suggest to mock the methods:
const mock1: any = {
methodToMock: jest.fn(() => {})
};

Related

In Jest, how to run a piece of code to do mock before each describe block?

There are hundreds of jest test files, and in each unit test files there could be mutiple describe block.
Is there a config or method to automatically run a block of code to do mock and setup before each describe block?
I know a brutal method which is to put beforeAll() in each describe block in hundreds of files, but it is too much editing. I tried the jest config object, but didn't find any useful option.
You can use setupFilesAfterEnv config.
For example, I will mock the axios module for all test files. In order to make sure that your tests use the mocked axios instead of the actual axios implementation, update your jest.config.js, by adding setupFileAfterEnv, as follows:
./a.test.ts:
import axios from 'axios';
describe('66341555 - a', () => {
it('should pass', () => {
expect(jest.isMockFunction(axios)).toBeTruthy();
});
});
./b.test.ts:
import axios from 'axios';
describe('66341555 - b', () => {
it('should pass', () => {
expect(jest.isMockFunction(axios)).toBeTruthy();
});
});
axios.mock.js:
jest.mock('axios');
jest.config.js:
module.exports = {
preset: 'ts-jest/presets/js-with-ts',
setupFilesAfterEnv: ['./axios.mock.js'],
};
test result:
PASS examples/66341555/b.test.ts
PASS examples/66341555/a.test.ts
Test Suites: 2 passed, 2 total
Tests: 2 passed, 2 total
Snapshots: 0 total
Time: 3.493 s, estimated 4 s
Here is a real-world example: https://github.com/yeahoffline/redis-mock#example-usage

Unit testing for REST API using node Js

I want to write unit testing for my REST API calls(Using mocha and chai).
Can anyone provide me better guide or any previously written code ,so that I can perform easily.
There are multiple guides through internet to start with mocha and chai. As, for example, the official documentation:
Mocha documentation
Chai documentation
Using npm you can install both:
Mocha: npm install --save-dev mocha
Chai: npm install chai
Also, for HTTP you need chai-http: npm install chai-http
With this you can start to code your tests.
First of all, into your test file you need import packages
var chai = require('chai'), chaiHttp = require('chai-http');
chai.use(chaiHttp);
And also use the assertion you want, for example:
var expect = chai.expect;.
Tests use this schema:
describe('Test', () => {
it("test1", () => {
})
it("test2", () => {
})
})
Where describe is to declare a 'suite' of tests. And inside every suite you can place multiple tests, even another suite.
If you execute this code using mocha yourFile.js you will get:
Test
√ test1
√ test2
Now you can start to add routes to test. For example somthing like this:
it("test1", () => {
chai.request('yourURL')
.get('/yourEndpoint')
.query({value1: 'value1', value2: 'value2'})
.end(function (err, res) {
expect(err).to.be.null;
expect(res).to.have.status(200);
});
})
And if you want to use your own express app, you can use
var app = require('../your/app')
...
it("test1", () => {
chai.request(app)
...
}
...
And also exists multiple more options describe into Chai documentation.

TestCafe 'dynamic' tests cases

I created a few e2e sanity tests for my current project using TestCafe. These tests are standard TestCafe tests:
fixture(`Basic checkout flow`)
test('Main Flow', async (t) => {
});
I would like to execute this test for multiple site locales and for multiple channels. i.e. I need this test to run for nl_nl, nl_be, en_gb, .. and also for channels like b2c, b2b, ...
The easiest way is to create a loop in the test itself to loop over the locales and channels, but I want to run these test concurrently.
I tried to create a function to dynamically generate these tests, but TestCafe can't seem to detect the tests then.
dynamicTest('Main Flow', async (t) => {
});
function dynamicTest(testName, testFn) => {
const channels = ['b2c']
channels.forEach((channel) => {
test(`[Channel] ${channel}] ${testName}`, testFn);
});
};
Is there a better way of doing this? The only solution I see is running the test script multiple times from Jenkins to have concurrency.
more detailed code:
import HomePage from '../../page/HomePage/HomePage';
import EnvUtil from '../../util/EnvUtil';
const wrapper = (config, testFn) => {
config.locales.forEach(async locale =>
config.channels.forEach(async channel => {
const tstConfig = {
locale,
channel
};
tstConfig.env = EnvUtil.parse(tstConfig, config.args.env);
testConfig.foo = await EnvUtil.get() // If I remove this line it works!
testFn(config, locale, channel)
})
);
};
fixture(`[Feature] Feature 1`)
.beforeEach(async t => {
t.ctx.pages = {
home: new HomePage(),
... more pages here
};
});
wrapper(global.config, (testConfig, locale, channel) => {
test
.before(async (t) => {
t.ctx.config = testConfig;
})
.page(`foo.bar.com`)
(`[Feature] [Locale: ${locale.key}] [Channel: ${channel.key}] Feature 1`, async (t) => {
await t.ctx.pages.home.header.search(t, '3301');
.. more test code here
});
});
If I run it like this I get a "test is undefined" error. Is there something wrong in the way I'm wrapping "test"?
Using TestCafe of version 0.23.1, you can run tests imported from external libraries or generated dynamically even if the test file you provide does not contain any tests.
You can learn more here: Run Dynamically Loaded Tests

XMLHttpRequest is not defined when testing react-native app with jest

i am trying to test a apiwrapper in a react-native based app using jest (integration testing).
When i run it in the iOs simulator everything runs fine however it wont run my jest tests correctly - i always get:
ReferenceError: XMLHttpRequest is not defined
when i try to run tests using my api wrapper, eg.:
it('Login successful with correct data', () => {
let api = Api.getInstance();
return api.login("test", "testpass")
.then(result => expect(result).toEqual('login_successful'));
});
the api class i am trying to test here does use the fetch api (not vanilla xhr). I assume its something related to jest trying to mock something but have not found a way to make it work yet.
Thanks in advance.
In my case, I'm not testing the search code but only importing it somewhere in my code path, so I decided to just mock it at the global level in a setup.js file (loaded using --require at test run). The following works for me:
// needed in react-instantsearch
class XMLHttpRequest {}
global.XMLHttpRequest = XMLHttpRequest;
I had a similar problem with lokka using XMLHttpRequest. I made a mock for lokka, which my api wrapper class depends on. You could try mocking your api wrapper.
This is what my lokka mock looks like for now. I'll add more to it when I start testing error handling.
export default class {
query() {
return new Promise(resolve => {
resolve(200);
});
}
}
You might be able to mock your api wrapper with something similar:
export default class Api {
getInstance() {
\\ However you implemented getInstance
}
login(user, password) {
return new Promise(resolve => {
resolve('login_successful');
});
}
}

How to dynamically mock ES6 modules with SystemJS?

I have a single-page application written in ES6. The code in transpiled server-side into classic javascript by babelJs, then loaded by SystemJs.
Javascript present in my html file:
System.config({
baseURL: '/js',
meta: {
'/js/*': { format: 'cjs' }
}});
System.defaultJSExtensions = true;
System.import("index.js")
.catch(function (error) {
console.error(error)
});
index.js:
import f1 from 'file1';
import f2 from 'file2';
// code here ...
Everything works fine. index.js is loaded, and all import statements are correctly executed.
Now, I want to create some pages with mocked ES6 modules, for testing purpose. My goal is to display pages by replacing model classes (contained in ES6 modules) with other static test classes.
Let's say I have 3 files: real_model.js, fake_model.js and component.js. component.js import the real model (import Model from 'real_model';).
How can I replace the real model by the fake one (in the component) dynamically ?
It's been a while since this question was posted, but maybe this solution might still be of help to anyone else.
With SystemJS it is possible to create a module on-the-fly using System.newModule. Then you can use System.set to overwrite existing modules with the new one. In our tests we use the following helper function to mock existing modules:
function mockModule(name, value) {
const normalizedName = System.normalizeSync(name);
System.delete(normalizedName);
System.set(normalizedName, System.newModule(Object.assign({ default: value }, value)));
}
Then, e.g. inside the beforeEach callback, we assign the mock and then import the module to be tested using System.import:
let [component, fake_model] = [];
beforeEach(() => {
// define mock
fake_model = { foo: 'bar' };
// overwrite module with mock
mockModule('real_model', fake_model);
// delete and reimport module
System.delete(System.normalizeSync('component'));
return System.import('src/testing').then((m) => {
component = m.default;
}).catch(err => console.error(err));
});
// test your component here ...
A big advantage of this approach is that you don't need an additional mocking library and it works solely with SystemJS.