Jest/Typescript: 在Jest和Typescript中模拟类的依赖项

15

我有一个依赖于类A的类B。我想测试类B中调用类A方法的内部方法。现在,我想通过模拟类A来对类B的方法进行单元测试。

我的代码结构:

class A {
  getSomething() {
     return "Something";
  }
}


class B {
  constructor(objectOfClassA: A) {
      this._objectOfClassA = objectOfClassA;

 }

 functionofClassBToTest() {
     const returnValueFromClassA = this._objectOfClassA.getSomething();

     return returnValueFromClassA;
 }
}

我目前尝试过的:

import ....
import { mocked } from 'jest-mock';

jest.mock("./A", () => {
    return {
        A: jest.fn().mockImplementation(() => {
            return {
                getSomething: getSomethingMock
            }
        })
    };
});

const getSomethingMock = jest.fn().mockImplementation(() => {
    return "Mock value";
});

const mockA = mocked(A, true);

test("test functionofClassBToTest", () => {
    const classBToTest = new B(mockA);

    expect(classBToTest.functionofClassBToTest.toStrictEqual("Mock value");
});


我遇到的错误如下:

TypeError: this._objectOfClassA.getSomething is not a function

注意:我不想在我的测试函数内初始化一个A类对象。我只想模拟这个类。

我还在StackOverflow上找到了一些相关的帖子: Post1Post2,但都没有起作用。

更新:感谢James的下面的回答,这个问题已经解决了。对于包含私有成员的类的模拟,我提出了另一个SO问题。请务必阅读。

1个回答

13

考虑到Typescript是基于结构类型的,因此可以通过直接字面量构建一个与A类接口匹配的对象,并将其传递给B类。

例如:

const mockA: jest.Mocked<A> = {
  getSomething: jest.fn()
};

const b = new B(mockA);

expect(mockA.getSomething)
    .toHaveBeenCalled();

假设mockA完全匹配类A的接口,则不应生成类型错误。

要模拟A方法的返回值,请参考使用Jest模拟单个函数。

这证明比尝试模拟整个模块更简单,更简洁。 由于您已将IoC用作模式,因此不需要模拟模块。

您还有一个拼写错误。 B类将实例变量分配给只有一个下划线的实例变量,但然后在具有两个下划线的实例变量上调用该方法。


感谢@james-dunne的回答。它解决了我的问题。这里只有一件事要补充:在创建mockA时,我必须像这样编写它:const mockA: jest.Mocked<A> = { getSomething: jest.fn() }; 注意:SO中的问题是由于笔误而写错的。谢谢。 - aniket singh
我已更新答案以反映您如何使其工作,谢谢 :) - James Dunne

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接