Jest:模拟传递给构造函数的依赖项

Rau*_*uno 1 unit-testing node.js typescript koa jestjs

我一直试图模拟通过构造函数传入的类,并且到目前为止我遇到的所有示例都在构造函数内初始化了依赖项。根据我的理解,jest 用其重写的构造函数替换了此类依赖项,但因为我自己传递依赖项,所以在初始化时我需要一个可以通过的实例UnderTest

对于它的价值,我理想地寻找 Mockito 式的行为,类似的东西。

const mockedDependency = ???
const underTest = new UnderTest(mockedDependency)

...
Proceed to write tests for underTest

Run Code Online (Sandbox Code Playgroud)

这是我要测试的代码。请假设它MockedDependency有自己的依赖项,也传递给构造函数。

export default class UnderTest {

  private mockedDependency : MockedDependency

  constructor(mockedDependency: MockedDependency) {
    this.mockedDependency = mockedDependency
  }

  public methodUnderTest(parameter: string) {
    const mockedResult = this.mockedDependency.returnSomething(parameter)
    return this.doSomethingElse(mockedResult)
  }

  public methodUnderTest2(parameter1: string, parameter2: string) {
    const mockedResult = this.mockedDependency.returnSomething2(parameter1, parameter2)
    return this.doSomethingElse(mockedResult)
  }

  private doSomethingElse(mockedResult: string) {
    return mockedResult
  }
}
Run Code Online (Sandbox Code Playgroud)

您将如何进行单元测试UnderTest课程?mockedDependency在每个测试中或通过输入设置方法结果的方法的奖励点。

编辑: 对于那些偶然发现同样问题的人来说,一个可能的解决方案:

可以将变量强制转换为所需的对象并重写方法,如下所示:

const mockedDependency = {
  returnSomething(parameter: string) {
    return parameter    
  }
} as MockedDependency

const underTest = new UnderTest(mockedDependency)
Run Code Online (Sandbox Code Playgroud)

它远非完美,但适用于更简单的情况。

提前致谢!

sli*_*wp2 5

这是解决方案:

\n\n

UnderTest.ts:

\n\n
export interface MockedDependency {\n  returnSomething(...args: any[]): any;\n  returnSomething2(...args: any[]): any;\n}\n\nexport default class UnderTest {\n  private mockedDependency: MockedDependency;\n\n  constructor(mockedDependency: MockedDependency) {\n    this.mockedDependency = mockedDependency;\n  }\n\n  public methodUnderTest(parameter: string) {\n    const mockedResult = this.mockedDependency.returnSomething(parameter);\n    return this.doSomethingElse(mockedResult);\n  }\n\n  public methodUnderTest2(parameter1: string, parameter2: string) {\n    const mockedResult = this.mockedDependency.returnSomething2(parameter1, parameter2);\n    return this.doSomethingElse(mockedResult);\n  }\n\n  private doSomethingElse(mockedResult: string) {\n    return mockedResult;\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

UnderTest.spec.ts:

\n\n
import UnderTest, { MockedDependency } from \'./UnderTest\';\n\nconst mockedDeps: jest.Mocked<MockedDependency> = {\n  returnSomething: jest.fn(),\n  returnSomething2: jest.fn()\n};\n\nconst underTest = new UnderTest(mockedDeps);\n\ndescribe(\'UnderTest\', () => {\n  afterEach(() => {\n    jest.resetAllMocks();\n  });\n  describe(\'#methodUnderTest\', () => {\n    it(\'should correctly\', () => {\n      mockedDeps.returnSomething.mockReturnValueOnce(\'mocked result\');\n      const actualValue = underTest.methodUnderTest(\'1\');\n      expect(actualValue).toBe(\'mocked result\');\n      expect(mockedDeps.returnSomething).toBeCalledWith(\'1\');\n    });\n  });\n\n  describe(\'#methodUnderTest2\', () => {\n    it(\'should correctly\', () => {\n      mockedDeps.returnSomething2.mockReturnValueOnce(\'mocked result\');\n      const actualValue = underTest.methodUnderTest2(\'2\', \'3\');\n      expect(actualValue).toBe(\'mocked result\');\n      expect(mockedDeps.returnSomething2).toBeCalledWith(\'2\', \'3\');\n    });\n  });\n});\n
Run Code Online (Sandbox Code Playgroud)\n\n

单元测试结果与 100% 覆盖率报告:

\n\n
 PASS  src/stackoverflow/55966013/UnderTest.spec.ts\n  UnderTest\n    #methodUnderTest\n      \xe2\x9c\x93 should correctly (5ms)\n    #methodUnderTest2\n      \xe2\x9c\x93 should correctly (1ms)\n\n--------------|----------|----------|----------|----------|-------------------|\nFile          |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |\n--------------|----------|----------|----------|----------|-------------------|\nAll files     |      100 |      100 |      100 |      100 |                   |\n UnderTest.ts |      100 |      100 |      100 |      100 |                   |\n--------------|----------|----------|----------|----------|-------------------|\nTest Suites: 1 passed, 1 total\nTests:       2 passed, 2 total\nSnapshots:   0 total\nTime:        3.597s, estimated 8s\n
Run Code Online (Sandbox Code Playgroud)\n\n

这是完成的演示: https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/55966013

\n