在模拟Node依赖项时,我碰巧遇到了以下库:
它们似乎都或多或少地做同样的事情:允许你模拟require()调用(除了Sinon几乎嘲笑所有东西).它们似乎都需要一些非常复杂的设置,注意传递给字符串的确切语法require- 在重构期间不是很好.
每个图书馆的利弊是什么?我何时会选择一个而不是另一个?每个库都擅长的示例用例是什么?这个领域的其他产品还有哪些更好?
我在Express中有以下内容
//index.js
var service = require('./subscription.service');
var auth = require('../auth/auth.service');
var router = express.Router();
router.post('/sync', auth.isAuthenticated, service.synchronise);
module.exports = router;
Run Code Online (Sandbox Code Playgroud)
我想覆盖或模拟isAuthenticated返回此
auth.isAuthenticated = function(req, res, next) {
return next();
}
Run Code Online (Sandbox Code Playgroud)
这是我的单元测试:
it('it should return a 200 response', function(done) {
//proxyquire here?
request(app).post('/subscriptions/sync')
.set('Authorization','Bearer '+ authToken)
.send({receipt: newSubscriptionReceipt })
.expect(200,done);
});
Run Code Online (Sandbox Code Playgroud)
我尝试使用proxyquire模拟index.js - 我想我需要存根路由器?我也试过在测试中覆盖
app.use('/subscriptions', require('./api/subscription'));
Run Code Online (Sandbox Code Playgroud)
必须有一种简单的方法来模拟它,所以我不需要验证请求.有任何想法吗?
我已经安装了proxyquire,我的ajax.test.tsx文件包含以下代码,只有2行
import * as proxyquire from 'proxyquire';
proxyquire.noCallThru();
Run Code Online (Sandbox Code Playgroud)
我的webpack代码如下
module.exports = {
entry: {
"book.service": './src/book.service.ts',
"ajax.test": './src/ajax.test.tsx'
},
output: {
filename: "[name].js",
path: __dirname + "/dist"
},
devtool: "source-map",
watch: true,
resolve: {
extensions: [".tsx", ".tsx", ".js", ".json", ".ts", '.d.ts']
},
module: {
rules: [
{ test: /\.tsx?$/, loader: "awesome-typescript-loader" },
{ enforce: "pre", test: /\.js$/, loader: "source-map-loader" }
]
},
externals: {
'react/lib/ExecutionEnvironment': true,
'react/addons': true,
'react/lib/ReactContext': 'window'
}
};
Run Code Online (Sandbox Code Playgroud)
我安装了proxyquire&@ types/proxyquire.当我运行webpack命令时,它会抛出以下错误
WARNING in ./~/proxyquire/lib/proxyquire.js
require.extensions is not …Run Code Online (Sandbox Code Playgroud) 我一直在成功使用Knex连接到后端数据库.但我希望能够对我的代码进行单元测试.有没有办法模拟数据库连接?
我尝试过使用proxyquire,但似乎无法让它工作.
问题似乎与Knex的初始化方式有关.
var knex = require('knex')({
client: 'mysql',
connection: {}
});
Run Code Online (Sandbox Code Playgroud)
我设置knex在我的单元测试中被嘲笑.
myService = proxyquire('../app/myService', {
'knex': knexProxy
});
Run Code Online (Sandbox Code Playgroud)
我的服务包括knex.
var knex = require('knex').knex,
Run Code Online (Sandbox Code Playgroud)
当我的服务运行查询时,它会失败.
var sql = knex("table_name");
sql.insert(rowToInsert, "auto_increment_id");
sql.then(function (insertId) {
resolve();
}, function (err) {
reject(err);
});
Run Code Online (Sandbox Code Playgroud)
出于某种原因,我似乎无法在尝试连接之前捕获请求.
我也试图创建一个自定义的Knex客户端,但这还没有成功.
我想对以下简化模块进行单元测试:
const Logger = require('logplease');
const logger = Logger.create('utils');
const tester = {
one: () => {
logger.log('called real one()');
tester.two();
},
two: () => {
logger.log('called real two()');
},
};
module.exports = {
one: tester.one,
two: tester.two
};
Run Code Online (Sandbox Code Playgroud)
我正在logplease使用Proxyquire替换外部依赖,这非常有效.但是我需要存根,two()因为我想进行单元测试,one()同时消除two()在实际代码中运行时产生的副作用.
it.only('stubbing functions on the "proxyquired" object under test', function(done) {
const loggerStub = {
create: () => {
return { log: (msg) => { console.log('fake logger: ', msg); } }; …Run Code Online (Sandbox Code Playgroud) 如果我们有三个模块的名称A,B并C因此模块A需要B和B要求C:这将是这一呼吁的效果?
var A = proxyquire('A', {'C': mockedModule})
Run Code Online (Sandbox Code Playgroud)
模块B会获得模拟或真实C模块吗?
我需要以某种方式模拟document对象,以便能够对传统的TypeScript类进行单元测试.该类导入另一个class(View.ts),它具有一个import第三方模块,并且反过来导入其他假定document存在的东西.
我的进口链:
controller.ts - > view.ts - > dragula - > crossvent - > custom-event
// Controller.ts:
import { View } from './View';
// View.ts:
const dragula = require('dragula');
// dragula requires crossvent, which requires custom-event, which does this:
module.exports = useNative() ? NativeCustomEvent :
'function' === typeof document.createEvent ? function CustomEvent (type, params) {
var e = document.createEvent('CustomEvent');
// ...
} : function CustomEvent (type, params) {
// ...
}
// …Run Code Online (Sandbox Code Playgroud) 我想在下面的代码中对导出的方法进行单元测试.我想模拟私有方法中的值来控制返回的Promise的拒绝/解析.client是已连接到数据库的node-postgres对象.
我知道我可以使用proxyquire来存根所需的库,但是如何模拟链接的方法.on('error', ...),.pipe(stream)以及.on('end', ...)我可以控制返回的值.
请注意,显示的导出方法是对实际方法的简化,导出importDomain是不可行的.
const copyFrom = require('pg-copy-streams').from
const request = require('request')
const Promise = require('bluebird')
// private
function importDomain (client, domain) {
return new Promise((resolve, reject) => {
let stream = client.query(copyFrom(`COPY ${domain.table} FROM STDIN;`))
let req = request(`${domain.url}`)
req.on('error', reject)
req.pipe(stream)
.on('error', reject)
.on('end', resolve)
})
}
// public
module.exports = (client) => {
let domain = someFunctionReturningDomain()
importDomain(client, domain)
}
Run Code Online (Sandbox Code Playgroud) 使用proxyquire,sinon和mocha.
我能够在第一次调用fetch时获取存根.但是在第二次提取调用中,这是递归的,我无法断言它.从输出看,断言可能在测试结束之前运行.second fetch在断言后你会看到控制台输出.
index.js
var fetch = require('node-fetch');
function a() {
console.log('function a runs');
fetch('https://www.google.com')
.then((e) => {
console.log('first fetch');
b();
})
.catch((e)=> {
console.log('error')
});
}
function b() {
fetch('https://www.google.com')
.then((e) => {
console.log('second fetch');
})
.catch((e)=> {
console.log('error')
});
}
a()
Run Code Online (Sandbox Code Playgroud)
测试:
describe('fetch test demo', ()=> {
it('fetch should of called twice', (done)=> {
fetchStub = sinon.stub();
fetchStub2 = sinon.stub();
fetch = sinon.stub();
fetchStub.returns(Promise.resolve('hello'));
fetchStub2.returns(Promise.resolve('hi'));
var promises = [ fetchStub, fetchStub2 ]
fetch.returns(Promise.all(promises));
proxy('../index', {
'node-fetch': …Run Code Online (Sandbox Code Playgroud) 由于某种原因proxquire找不到我的模块index.js。我一定是在做一些非常愚蠢或明显的事情而无法看到它。
错误:
invoicer
good request
1) "before all" hook
0 passing (9ms)
1 failing
1) invoicer good request "before all" hook:
Error: Cannot find module '../index.js'
at Function.Module._resolveFilename (module.js:338:15)
at Proxyquire._disableModuleCache (/Users/mario/projects/_invoice/print-invoice/node_modules/proxyquire/lib/proxyquire.js:218:19)
at Proxyquire._disableCache (/Users/mario/projects/_invoice/print-invoice/node_modules/proxyquire/lib/proxyquire.js:203:15)
at Proxyquire._withoutCache (/Users/mario/projects/_invoice/print-invoice/node_modules/proxyquire/lib/proxyquire.js:173:27)
at Proxyquire.load (/Users/mario/projects/_invoice/print-invoice/node_modules/proxyquire/lib/proxyquire.js:135:15)
at getTestedModule (/Users/mario/projects/_invoice/print-invoice/test/test.js:89:12)
at Context.<anonymous> (/Users/mario/projects/_invoice/print-invoice/test/test.js:69:28)
at Hook.Runnable.run (/usr/local/lib/node_modules/mocha/lib/runnable.js:218:15)
at next (/usr/local/lib/node_modules/mocha/lib/runner.js:259:10)
at Object._onImmediate (/usr/local/lib/node_modules/mocha/lib/runner.js:276:5)
at processImmediate [as _immediateCallback] (timers.js:345:15)
Run Code Online (Sandbox Code Playgroud)
奇怪的是,我对另一个应用程序的测试进行了相同的设置,并且在那里找到模块没有问题。我什至维护了相同版本的proxyquire,将其更改为最新版本仍然没有修复它。index.js存在于指定路径的目录中。
这是我的测试代码:
var chai = require('chai');
var sinonChai = require("sinon-chai");
var …Run Code Online (Sandbox Code Playgroud) proxyquire ×10
node.js ×6
unit-testing ×5
sinon ×4
javascript ×3
mocha.js ×2
mocking ×2
typescript ×2
express ×1
knex.js ×1
pg-copy ×1
reactjs ×1
stubs ×1
webpack ×1