这是我想在typescript中使用mocha-chai测试框架进行测试的类。我正在使用ts-mockito进行模拟。
export class ClassA implements IClassA {
private classAResource: IClassAResource;
constructor(){
this.classAResource= new ClassAResource();
}
public async cancel(jobid){
const job = this.classAResource.getJob(jobid);
//cancel logic
}
}ClassAResource类如下所示:
export class StreamResource implements IStreamResource {
private jobs: Map<string, Job>;
constructor(){
this.jobs= new Map();
}
public async createJob(): Promise<Job> {
//add the job to map
}
public async getJob(jobid): Promise<Job>{
//return the specified job item from map
}
}在我的测试中,我尝试模拟ClassAResource的getJob方法,如下所示,
const classAResource: IClassAResource = new ClassAResource ();
const classAResourceSpy = spy(classAResource);
when(classAResourceSpy.getJob(anyString())).thenResolve(job); 我像这样调用ClassA cancel方法,
classA.cancel(jobid)我希望cancel方法中的getJob调用被模拟并返回一个作业对象。
但是测试并没有按照我的预期进行。getJob没有出现在图片中,而Mock ()进入实际实现并返回未定义。
我在网上读到,这个问题是由于ClassAResource类中的构造函数初始化造成的。
我删除了构造函数并进行了尝试,现在getJob模拟可以工作了。
但是我需要构造函数来实例化map对象和维护作业的能力。
有没有什么变通方法可以让我在适当的地方用构造函数模拟getJob()?
我是不是做错了什么?
我对typescript和ts-mockito比较陌生,任何帮助都非常感谢。
发布于 2019-03-26 14:13:17
这实际上与TypeScript没有什么特别的关系,而是由于破坏了Dependency Inversion principle而导致的可测性问题。
在类的构造函数中实例化成员会导致可测试性问题,因为实例化的控制权掌握在被测代码手中(也称为“被测单元”、“被测类”等)。这意味着,您几乎无法控制正在测试的类将具有哪个实例。
有一些模仿库允许“恶意接管”某些类的实例化(至少对于Java,请参阅PowerMock),但它们应该非常谨慎地使用,如果有的话,因为它们有助于长期缺乏可测试性。
与从ClassA的构造函数实例化IClassAResource不同,您应该通过注入(DI、构造函数、设置器方法等)获取实例,或者至少使用工厂/构建器。这样,您的类将变得可测试,并且您的设计将得到改进。
一般来说,您应该遵守所有的SOLID原则,因为至少在目前,它们被认为是一组最准确、最简洁的好的OOP设计原则。
https://stackoverflow.com/questions/55350430
复制相似问题