由于使用 mysql 驱动程序需要您首先创建一个连接,并使用返回的连接控制器的 api - 您需要一个两步的方法。
有两种方法可以做到这一点。
存根createConnection,并让它返回一个存根连接
在设置过程中:
const sinon = require('sinon');
const mysql = require('mysql');
const {createConnection} = mysql;
let mockConnection;
sinon.stub(mysql, 'createConnection').callsFake((...args) => {
mockConnection = sinon.stub(createConnection.apply(mysql, args))
.expects('query').withArgs(.... )//program it how you like :)
return mockConnection;
})
const mockConnectionFactory =
sinon.stub(mysql)
.expects('createConnection')
拆解期间:
mysql.createConnection.restore();
注意这里query方法是在实例上模拟的,对底层机制没有影响,所以只有createConnection必须恢复。
在连接原型上存根 .query 方法
这种技术有点棘手,因为mysql 驱动程序没有正式公开它的导入连接。 (你可以只导入实现连接的模块,但不能保证任何重构都不会从那里移动它)。
所以为了获得对原型的引用——我通常会创建一个连接并向上遍历构造函数-原型链:
我通常会在一行中完成,但我将其分解为步骤并在此处进行解释:
在设置过程中:
const realConnection = mysql.createConnection({})
const mockTarget = realConnection.constructor.prototype;
//Then - brutally
consdt mock = sinon.mock(mockTarget).expect('query'....
//OR - as I prefer the surgical manner
sinon.stub(mockTarget, 'query').expect('query'....
拆解期间
//brutal
mock.restore()
// - OR - surgical:
mockTarget.query.restore()
请注意,我们不会在此处模拟 createConnection 方法。所有连接参数验证仍然会发生(我希望它们发生。我渴望使用最大的真实部件 - 因此模拟获得快速测试所需的绝对最小值)。但是 - query 在原型上被模拟,必须恢复。
另请注意,如果您进行外科手术,verify 将位于模拟方法上,而不是模拟目标上。
这里有一个很好的资源:@987654321@