Javascript 用Sinon存根类方法时出现的问题
我有一个具有以下类的NodeJS+Typescript应用程序:Javascript 用Sinon存根类方法时出现的问题,javascript,mocha.js,sinon,Javascript,Mocha.js,Sinon,我有一个具有以下类的NodeJS+Typescript应用程序: export default class OrderStreamWriter { private readonly redis: IORedis; private readonly orderStream: string; private readonly logger: LoggerFactory; constructor(redisHost: string, redisPort: number, redisP
export default class OrderStreamWriter {
private readonly redis: IORedis;
private readonly orderStream: string;
private readonly logger: LoggerFactory;
constructor(redisHost: string, redisPort: number, redisPass: string, orderStream: string) {
this.orderStream = orderStream;
this.redis = createRedisClient(redisHost, redisPort, redisPass);
this.logger = new LoggerFactory('streams/OrderStreamWriter');
}
public async write(msg: string): Promise<void> {
await this.redis.xadd(this.orderStream, '*', 'trade', msg).catch((err: Error) => {
this.logger.log(
`Error Writing message to stream (${this.orderStream}): ${err.message}. Quitting...`,
);
process.exit(1);
});
}
}
使用当前代码和注释行const writesub=sinon.stub(OrderStreamWriter.prototype,“write”)代码>我在运行测试时收到相同的错误:
TypeError:无法对不存在的属性进行存根写入
如何解决此问题?请提供要测试的TriggerContext
类的代码。是否确定导入测试文件并调用ObjectStreamWriter
的对象是正确的对象?我注意到该类是其文件的默认导出。对于使用注释行的测试,您可以将Writer
的定义更改为class Writer{write(){}
,并且给定的错误应该消失
// someclass.js
class SomeClass {
prop1;
prop2;
contructor(param1, param2) {
this.prop1 = param1;
this.prop2 = param2;
}
async someFunction(givenParam) {
// do something here
return "somedata";
}
}
// create a factory . This is what you will use to create an instance rather than using the new word ever time to create a new instance.
const someClassInstanceFactory = (param1, param2) => {
return new SomeClass(param1, param2);
};
export default { someClassInstanceFactory, SomeClass };
// ********************************************************
// somemodule.js
// this file uses the class we created above as below
import classAndFactory from "./someclass.js";
const moduleFunction = () => {
const instance = classAndFactory.someClassInstanceFactory(param1, param2);
// this line returns an instance of SomeClass . it's like calling new SomeClass(pram1, param2);
const result = instance.someFunction("givenParam");
console.log(result);
return result;
// result should be 'somedata'
// so how do we unit test moduleFunction and stub instance.someFunction when testing? ?
};
export default moduleFunction;
// *******************************************************************
// somemodule.test.js
import classAndFactory from "./../someclass.js";
import moduleFunction from "./somemodule.js";
const { someClassInstanceFactory, SomeClass } = classAndFactory;
// now if you want to stub any thing what you do is
describe("moduleFunction", () => {
const fakeSomeClassInstance = new SomeClass(1, 2);
// arrange
// stub the factory first to return your fake instance created above.
const expectedResut = "stubbed yoo";
sinon
.stub(classAndFactory, "someClassInstanceFactory")
.returns(fakeSomeClassInstance);
someFunctionStub = sinon
.stub(fakeSomeClassInstance, "someFunction")
.returns(expectedResut);
it("must call someFunction function with required argument", () => {
// act
const result = moduleFunction();
// assert
sinon.assert.calledOnce(someFunctionStub);
assert.equals(result, expectedResut);
});
});
// someclass.js
class SomeClass {
prop1;
prop2;
contructor(param1, param2) {
this.prop1 = param1;
this.prop2 = param2;
}
async someFunction(givenParam) {
// do something here
return "somedata";
}
}
// create a factory . This is what you will use to create an instance rather than using the new word ever time to create a new instance.
const someClassInstanceFactory = (param1, param2) => {
return new SomeClass(param1, param2);
};
export default { someClassInstanceFactory, SomeClass };
// ********************************************************
// somemodule.js
// this file uses the class we created above as below
import classAndFactory from "./someclass.js";
const moduleFunction = () => {
const instance = classAndFactory.someClassInstanceFactory(param1, param2);
// this line returns an instance of SomeClass . it's like calling new SomeClass(pram1, param2);
const result = instance.someFunction("givenParam");
console.log(result);
return result;
// result should be 'somedata'
// so how do we unit test moduleFunction and stub instance.someFunction when testing? ?
};
export default moduleFunction;
// *******************************************************************
// somemodule.test.js
import classAndFactory from "./../someclass.js";
import moduleFunction from "./somemodule.js";
const { someClassInstanceFactory, SomeClass } = classAndFactory;
// now if you want to stub any thing what you do is
describe("moduleFunction", () => {
const fakeSomeClassInstance = new SomeClass(1, 2);
// arrange
// stub the factory first to return your fake instance created above.
const expectedResut = "stubbed yoo";
sinon
.stub(classAndFactory, "someClassInstanceFactory")
.returns(fakeSomeClassInstance);
someFunctionStub = sinon
.stub(fakeSomeClassInstance, "someFunction")
.returns(expectedResut);
it("must call someFunction function with required argument", () => {
// act
const result = moduleFunction();
// assert
sinon.assert.calledOnce(someFunctionStub);
assert.equals(result, expectedResut);
});
});