如何模拟使用ts Mockito在Typescript中的另一个类中初始化的类方法?

时间:2019-03-26 05:32:46

标签: typescript unit-testing jsmockito

这是我要在打字稿中使用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取消方法,

classA.cancel(jobid)

我希望对cancel方法中的getJob调用进行模拟并返回作业对象。

但是测试未达到我的预期。模拟没有出现,getJob()进入实际实现并返回未定义。

我在线阅读,这个问题是由于ClassAResource类中的构造函数初始化。

我删除了构造函数并尝试了,现在getJob模拟工作了。

但是我需要构造函数来实例化map对象和维护作业的能力。

是否存在一些变通办法,可以通过该变通办法来模拟具有构造函数的getJob()?

我在这里做错什么了吗?

我对打字稿和ts-mockito还是比较陌生,非常感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

这确实与TypeScript完全无关,而是由于违反Dependency Inversion principle而引起的可测试性问题。
在类的构造函数中实例化成员会导致可测试性问题,因为对实例化的控制权在被测代码(也就是“被测单元”,“被测类”等)的手中。这意味着,您几乎无法控制要测试的类具有哪个实例。

有些模拟库允许对某些类的实例进行“恶意接管”(至少对于Java,请参见PowerMock),但应尽量少用(如果有的话),因为它们会有所贡献导致缺乏可测试性。

您应该通过注入(DI,构造函数,setter方法等)获取实例,或者至少使用工厂/构建器,而不是从IClassAResource的构造函数实例化ClassA。这样,您的班级将成为可测试的,并且您的设计将得到改善。

通常,您应该遵守所有SOLID原则,因为至少在目前,它们被认为是最准确,最简洁的良好OOP设计原则。