I cloud manage to run run Mocha tests in the browser using ES6 / Typescript like that:
// test.ts
import 'mocha/mocha.css';
import * as M from 'mocha/mocha-es2018';
import { expect } from 'chai';
M.setup('bdd');
// import more tests here
describe('test', () => {
it('test1', () => {
expect(true).to.true;
})
});
M.run();
The build works (using vite), the html page shows up - all nice and fine. BUT of course I would love to add more tests like that:
import './unit/sum.spec.ts';
// more imports
Doing so - will cause this error:
Uncaught ReferenceError: describe is not defined
Is there any way to make all those »mocha functions« globally available using es6?
I could finally make it like that:
import 'mocha/mocha.css';
import * as M from 'mocha/mocha-es2018';
(async () => {
M.setup('bdd');
await Promise.all([
import('./unit/add.spec'),
import('./unit/sub.spec'),
import('./component/calc.spec')
]);
M.run();
})();
Related
I am very new to NodeJS and JS as well. I have tried reading about resources like babel and rewire which help in resolving dependencies of ES6. But ended up being confused.
I am trying to write unit test for a JS runtime file which has import statements. The issue is that this file is a runtime file. This means that the import module only works when running in browser inside the dependent platform/application.
runtimeFile.js
import {something} from 'other-module'
function foo(){
}
export const toBeTested = {
foo
}
unitTest.js
const toBeTested = require('./runtimeFile').toBeTested
describe('some test', () => {
it('test a func', () => {
const result = tobeTested.foo();
});
});
When i try to run this unit test using mocha getting:
SyntaxError: Unexpected token {
This is for the import statement in runtimeFile.js.
So my question is around:
How do i mock the import statement
I am not sure what configuartion i need to do in order to get rid of this syntax error
I can provide more information as needed
index.js
import { Time} from './service/passport';
passport.js
const Time = async () => {
console.log('done');
}
export { Time }
I am using EcmaScript or es6 in node.js but when I try to export above module it is giving me error Can't find module but I have exported module don't know why still getting error any help will be appreciated
Need to add file extension only instead of
import { Time} from './service/passport';
use
import { Time} from './service/passport.js';
it will be done
So I have this import statement in a module that I'm trying to test using jest 25.1 running on node 11.1.0. The import statement is for a module that is only available when running on the jvm's nashorn runtime, so I'm using jest's virtual mock to control the behavior in the unit tests. Here's what the import statement looks like in the module under test:
import RequestBuilder from 'nashorn-js/request_builder'
...and after the other lines in the import block, this:
const request = RequestBuilder.create('some-string')
.sendTo('some-other-string')
.withAction('yet-another-string')
.getResultWith( consumer => consumer.result( consumer.message().body() ) )
export const functionA = () => {...} // uses 'request' variable
export const functionB = () => {...} // uses 'request' variable
In the corresponding .spec file, I have this virtual mock setup:
const mockGetResultWith = {
getResultWith: jest.fn()
}
const mockWithAction = {
withAction: jest.fn().mockImplementation(() => mockGetResultWith)
}
const mockSendTo = {
sendTo: jest.fn().mockImplementation(() => mockWithAction)
}
const mockBuilder = {
create: jest.fn().mockImplementation(() => mockSendTo)
}
jest.mock(
'nashorn-js/request_builder',
() => mockBuilder,
{ virtual: true }
)
require('nashorn-js/request_builder')
import { functionA, functionB } from './module-under-test'
I have been trying unsuccessfully to get past this failure from jest:
● Test suite failed to run
TypeError: Cannot read property 'create' of undefined
35 | }
36 |
> 37 | const verify = RequestBuilder.create('some-string')
| ^
38 | .sendTo('some-other-string')
39 | .withAction('yet-another-string')
40 | .getResultWith( consumer => consumer.result( consumer.message().body() ) )
I've tried all kinds of different mock structures, using require vs import, etc, but haven't found the magic bullet.
As near as I can tell, it does not appear that the RequestBuilder import statement is even invoking the virtual mock. Or at least, if I add console.log() statements to the virtual mock factory function, I never see those log messages in the output.
Anybody have any idea what I'm missing or what else to try? I have pretty much the same pattern in use in other parts of the code, where this setup works, but for some mystical reason with this module, I can't get the virtual mock working. Any help is greatly appreciated.
So, the problem here turned out to be jest's implementation of import vs require in the .spec file.
By changing this line:
import { functionA, functionB } from './module-under-test'
To this:
const module = require('./module-under-test')
const functionA = module.functionA
const functionB = module.functionB
The module under test now loads successfully, and the tests run as expected.
I have no explanation for this, and haven't been able to find jest documentation describing why I'd get any different behavior between require vs import. In fact, I have the mock configuration setup before any import statements as described here:
https://github.com/kentcdodds/how-jest-mocking-works
If anybody out there understands what's going on with this import behavior, or has a link describing what I'm missing, I'd sure appreciate the info.
I want to run mocha tests in a TDD manner (--watch mode), which works fine.
But I have a "global setup.js" file, which mocks part of the application, that is used by most tests.
If I run the tests normally or in watch mode for the first time everything is fine because the setup script loads.
If a test or source file is changed, however, only the relevant tests run (sounds awesome in theory) but since my global mocking script is not run the tests fail.
How can I execute a setup script each time (once per overall test run) even in watch mode with mocha?
This is the command I use:
vue-cli-service test:unit --watch
# pure mocha would be (I assume)
mocha 'tests/**/*.spec.js' --watch
I have tried using the --require and --file option, but they are also not rerun on file changes.
I am using a vue app created with the VUE CLI and this is how my code looks
// setup.spec.js
import { config } from "#vue/test-utils";
before(() => {
config.mocks["$t"] = () => {};
});
// some_test.spec.js
import { expect } from "chai";
import { shallowMount } from "#vue/test-utils";
import MyComp from "#/components/MyComp.vue";
describe("MyComp", () => {
it("renders sth", () => {
const wrapper = shallowMount(MyComp);
expect(wrapper.find(".sth").exists()).to.be.true;
});
});
This isn't a very satisfying answer because it feels like there should be a better way but you can import your setup script into the individual test files.
For example:
// some_test.spec.js
import 'setup.spec.js' //<-- this guy right here
import { expect } from "chai";
import { shallowMount } from "#vue/test-utils";
import MyComp from "#/components/MyComp.vue";
describe("MyComp", () => {
it("renders sth", () => {
const wrapper = shallowMount(MyComp);
expect(wrapper.find(".sth").exists()).to.be.true;
});
});
Feels sub optimal, but it is better than replicating logic everywhere.
Have you tried utilizing .mocharc.js file to setup your mocha configurations before you run a test?
'use strict';
module.exports = {
package: './package.json',
watch: true,
timeout: 100000
};
I'm trying to fiddle with Ecmascript 6 modules using webpack + traceur to transpile to ES5 CommonJS, but I'm having trouble successfully unit testing them.
I tried using Jest + traceur preprocessor, but the automocking and dependency names seem to get screwy, plus I can't seem to get sourceMaps to work with Jest and node-inspector debugging.
Is there a better framework to unit test ES6 modules?
I've started employing the import * as obj style within my tests, which imports all exports from a module as properties of an object which can then be mocked. I find this to be a lot cleaner than using something like rewire or proxyquire or any similar technique.
I can't speak for traceur which was the framework used in the question, but I've found this to work with my setup of Karma, Jasmine, and Babel, and I'm posting it here as this seems to be the most popular question of this type.
I've used this strategy most often when needing to mock Redux actions. Here's a short example:
import * as exports from 'module-you-want-to-mock';
import SystemUnderTest from 'module-that-uses-above-module';
describe('your module', () => {
beforeEach(() => {
spyOn(exports, 'someNamedExport'); // mock a named export
spyOn(exports, 'default'); // mock the default export
});
// ... now the above functions are mocked
});
If you are using Webpack another option that has a little more flexibility than rewire is inject-loader.
For example, in a test that is bundled with Webpack:
describe('when an alert is dismissed', () => {
// Override Alert as we need to mock dependencies for these tests
let Alert, mockPubSub
beforeEach(() => {
mockPubSub = {}
Alert = require('inject!./alert')({
'pubsub-js': mockPubSub
}).Alert
})
it('should publish \'app.clearalerts\'', () => {
mockPubSub.publish = jasmine.createSpy()
[...]
expect(mockPubSub.publish).toHaveBeenCalled()
})
})
inject-loader, in a similar manner to proxyquire at least allows one to inject dependencies before importing whereas in rewire you must import first and then rewire which makes mocking some components (e.g. those that have some initialization) impossible.
Hi you could use proxyquire:
import assert from 'assert';
import sinon from 'sinon';
import Proxyquire from 'proxyquire';
let proxyquire = Proxyquire.noCallThru(),
pathModelLoader = './model_loader';
describe('ModelLoader module.', () => {
it('Should load all models.', () => {
let fs, modelLoader, ModelLoader, spy, path;
fs = {
readdirSync(path) {
return ['user.js'];
}
};
path = {
parse(data) {
return {name: 'user'};
}
};
ModelLoader = proxyquire(pathModelLoader, {'fs': fs, 'path': path});
modelLoader = new ModelLoader.default();
spy = sinon.spy(modelLoader, 'loadModels');
modelLoader.loadModels();
assert(spy.called);
});
});
I actually got this to work by dropping Jest and going with Karma + Jasmine + Webpack and using https://github.com/jhnns/rewire to mock dependencies
Proxyquire will help you, but it not gonna to work with modern webpack+ES6 modules, ie "aliases".
import fs from 'fs';
import reducers from 'core/reducers';
...
proxyquire('../module1', {
'fs': mockFs, // this gonna work
'core/reducers': mockReducers // what about this?
});
that will not work.
As long you can mock fs - you cannot mock reducers.
You have to specify real name of dependency, after any webpack or babel transformation. Normally - name relative to module1 location. May be '../../../shared/core/reducers'. May be not.
There is drop in solutions - https://github.com/theKashey/proxyquire-webpack-alias (stable, based on fork of proxyquire) or https://github.com/theKashey/resolveQuire (less stable, can be run upon original proxyquire)
Both of them works as well, and will mock any ES6 module(they are dam good) in a proxyquire way(it is a good way)