我有一些要转换为ES6的ES5示例项目:
https://github.com/stefaneidelloth/testDemoES5
https://github.com/stefaneidelloth/testDemoES6
示例包括从类Qux
继承的类Baa
。
在测试Qux
时,我想模拟Baa
。
对于 ES5 ,我使用 Squire.js 模拟AMD模块依赖关系,并且单元测试工作正常。
不幸的是,我找不到直接支持ES6(=“ ESMAScript 2015 Language”,ES2015)模块的测试框架。我们现在有2019年,ES2015仍然没有单元测试?我已经花了很多时间尝试使这些测试正常工作……并且我的印象是我的方法缺少一些东西。
由于找不到直接对ES6测试的支持,因此我尝试坚持使用业力,并使用Webpack将ES6模块代码转换为ES5 AMD模块进行测试。
首先让我们考虑将业力与已转换为AMD模块的requirejs和ES6代码结合使用。
A。。如果我尝试使用 Squire 模拟翻译的类Baa
(模块'src / baa'),则此方法将不起作用更多。 Webpack将所有依赖项放在一个文件中,当使用'src / qux'时,不考虑我注入的'src / baa'。
qux.test.js:
define([
'squire'
], function (
Squire
) {
describe('Qux', function(){
var sut;
beforeEach(function(done){
var injector = new Squire();
injector.mock('src/baa', createBaaMock());
injector.require([
'src/qux'
], function(
quxModule
){
var Qux = quxModule.default;
sut = new Qux('qux');
done();
});
});
it('quxMethod', function(){
expect(sut.quxMethod()).toEqual('quxMethod');
});
it('baaMethod', function(){
expect(sut.baaMethod()).toEqual('baaMockedMethod');
});
it('overridableMethod', function(){
expect(sut.overridableMethod()).toEqual('qux');
});
function createBaaMock(){
var BaaMock = function (name) {
this.name = name;
};
BaaMock.prototype.baaMethod = function () {
return 'baaMockedMethod';
}
var moduleMock = {
default: BaaMock
}
return moduleMock;
}
});
});
=>我收到错误消息
期望'baaMethod'等于'baaMockedMethod'。
有关调试的更多信息。...转换为ES5的缺点是,在调试测试时,浏览器中运行的代码看起来与原始代码不同(默认情况下)。因此,可能的错误很难识别。在这里有帮助的是:
使用Webpack模式“开发”而不是“生产”来避免缩小
启用devtool option of webpack to enable source mapping。这样,调试时,原始代码也会显示在浏览器中。
B。。我尝试使用 inject-loader ,它是Squire.js的替代方法,它了解Webpack: https://github.com/LeanKit-Labs/inject-loader
但是,这似乎是一个CommonJs模块,与我的业力+ requirejs项目不兼容:
qux.test.js:
describe('Qux', function(){
var sut;
beforeEach(function(done){
require(['inject!src/qux'],function(ModuleInjector){
var quxModule = ModuleInjector({
'src/baa': crateBaaMock()
});
var Qux = quxModule.default;
sut = new Qux('qux');
done();
});
});
it('quxMethod', function(){
expect(sut.quxMethod()).toEqual('quxMethod');
});
it('baaMethod', function(){
expect(sut.baaMethod()).toEqual('baaMockedMethod');
});
it('overridableMethod', function(){
expect(sut.overridableMethod()).toEqual('qux');
});
function createBaaMock(){
var BaaMock = function (name) {
this.name = name;
};
BaaMock.prototype.baaMethod = function () {
return 'baaMockedMethod';
}
var moduleMock = {
default: BaaMock
}
return moduleMock;
}
});
=>我收到错误消息
未捕获的ReferenceError:模块未定义。
我也尝试过mock-loader,但没有成功。
C。。我尝试不使用AMD模块,而是将CommonJs模块用作Webpack编译的目标。但是,我没有设法同时使用commonjs预处理器和karma的and webpack预处理器。
D。。我尝试将System.js而不是require.js和Webpack与Karma一起使用。但是,karma-system.js依赖于system.js(0.19.47)的一个很旧的版本,我无法正常运行。
E。在回答related and old SO question时,有人建议使用“ import * as obj”样式导入模块形式的类,然后在默认导出来模拟该类。
但是,如果多个测试正在使用该“修改后的模块”(无法重新定义属性“默认”),则可能会导致问题。
由于webpack不会动态加载依赖项,因此以下测试失败:
define([
'src/baa',
'src/qux'
],function(
baaModule,
quxModule
){
describe('Qux', function(){
var sut;
beforeEach(function(done){
baaModule.default = createBaaMock();
var Qux = quxModule.default;
sut = new Qux('qux');
done();
});
it('quxMethod', function(){
expect(sut.quxMethod()).toEqual('quxMethod');
});
it('baaMethod', function(){
expect(sut.baaMethod()).toEqual('baaMockedMethod');
});
it('overridableMethod', function(){
expect(sut.overridableMethod()).toEqual('qux');
});
function createBaaMock(){
var BaaMock = function (name) {
this.name = name;
};
BaaMock.prototype.baaMethod = function () {
return 'baaMockedMethod';
}
var moduleMock = {
default: BaaMock
}
return moduleMock;
}
});
});
总而言之,我发现了许多过时且不完整的方法来测试ES6模块,但似乎没有一种方法能很好地解决问题。
=> 如果我应该坚持业力,我该如何调整我的测试qux.test.js示例代码(可能还有我的配置文件)以正确模拟类{{1} }?
=> 是否可以告诉webpack 将翻译后的模块分开,以便我可以轻松地使用Squire.js注入依赖项?
=> 在浏览器中进行单元测试ES6模块是否有更好的最新工作流程/框架?有人试图用业力来开玩笑吗?
相关内容:
答案 0 :(得分:0)
我从业力切换到jest,这是一个有效的演示项目:
https://github.com/stefaneidelloth/testDemoES6Jest
工作流仍然基于转译器(babel),但这发生在后台,并没有真正影响开发经验。
模拟某些ES6模块的示例测试代码:
import Qux from './../src/qux.js';
jest.mock('./../src/baa.js', () => {
return class BaaMock {
constructor(name){
this.name = name;
}
baaMethod(){
return 'baaMockedMethod';
}
}
});
describe('Qux', function(){
var sut;
beforeEach(function(){
sut = new Qux('qux');
});
it('quxMethod', function(){
expect(sut.quxMethod()).toEqual('quxMethod');
});
it('baaMethod', function(){
expect(sut.baaMethod()).toEqual('baaMockedMethod');
});
it('overridableMethod', function(){
expect(sut.overridableMethod()).toEqual('qux');
});
});
示例package.json(已启用测试命令的代码覆盖率):
{
"name": "testDemoES6Jest",
"version": "1.0.0",
"main": "index.js",
"repository": "https://github.com/stefaneidelloth/testDemoES6Jest.git",
"author": "Stefan Eidelloth <matameko@posteo.de>",
"license": "MIT",
"dependencies": {},
"devDependencies": {
"@babel/core": "^7.5.5",
"@babel/preset-env": "^7.5.5",
"babel-jest": "^24.8.0",
"jest": "^24.8.0",
"jest-cli": "^24.8.0",
"requirejs": "2.3.6"
},
"scripts": {
"test": "jest --coverage --collectCoverageFrom src/**/*.js ",
"debug": "node --inspect-brk ./node_modules/jest/bin/jest.js --watch --runInBand"
}
}
对于调试,有several options,例如:
a)VisualStudioCode ,以及Jest插件
(调试=>安装其他调试器=>笑话(“将Facebook的笑话高兴地使用”,https://github.com/jest-community/vscode-jest)
示例调试配置launch.json:
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Jest Tests",
"program": "${workspaceRoot}\\node_modules\\jest\\bin\\jest.js",
"args": [
"-i"
],
"internalConsoleOptions": "openOnSessionStart"
}
]
}
b)谷歌浏览器:
node --inspect-brk ./node_modules/jest/bin/jest.js
(可以在以下脚本中保存为您的package.json中的别名:{“ debug”:...并使用 npm run-script debug 运行)
打开Chrome浏览器并输入地址
chrome:// inspect
单击打开Node专用DevTools
将项目目录拖放到dev工具中以允许文件访问(仅需要一次)
打开要调试的文件并设置断点
在开发工具中单击继续以继续到所需的断点
另请参见
c)网络风暴
请参见https://blog.jetbrains.com/webstorm/2018/10/testing-with-jest-in-webstorm/
有关浏览器中的测试,请参见 * https://github.com/smooth-code/jest-puppeteer * https://developers.google.com/web/tools/puppeteer/get-started