关于单元测试:如何将Sinon与Typescript一起使用?

How do I use Sinon with Typescript?

如果我将sinon与typescript一起使用,那么如何将sinon模拟转换为对象的实例?

例如,将返回SinonMock,但我的受测控制器可能需要将特定服务传递给其构造函数。

1
2
3
var myServiceMock: MyStuff.MyService = <MyStuff.MyService (sinon.mock(MyStuff.MyService));

controllerUnderTest = new MyStuff.MyController(myServiceMock, $log);

sinon可以与Typescript一起使用吗?


如果您使用createStubInstance方法而不是mock,则Sinon可以非常轻松地基于构造函数创建存根。

使用mocha,chai,sinon和sinon-chai的示例可能如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import * as sinon from 'sinon';
import * as chai from 'chai';

// ... imports for the classes under test

const expect    = chai.expect;
const sinonChai = require("sinon-chai");

chai.use(sinonChai);

describe('MyController', () => {
    it('uses MyService', () => {

        let myService  = sinon.createStubInstance(MyStuff.MyService),
            controller = new MyStuff.MyController(myService as any, ...);

        // ... perform an action on the controller
        // that calls myService.aMethodWeAreInterestedIn

        // verify if the method you're interested in has been called if you want to
        expect(myService.aMethodWeAreInterestedIn).to.have.been.called;
    });
});

我已经发表了一篇文章,如果您想了解更多有关不同的测试双打以及如何将它们与Sinon.js一起使用的信息,可能会发现很有用。

希望这可以帮助!

一月


您可能需要使用类型断言来使类型变宽,然后再将其范围缩小到特定类型:

1
2
var myServiceMock: MyStuff.MyService =
    <MyStuff.MyService>  (sinon.mock(MyStuff.MyService));

只是为了阐明sinon的一种行为-尽管您传入了MyStuff.MyService,但是传递给mock方法的任何内容仅用于提供更好的错误消息。

如果要让模拟具有方法和属性,则需要添加它们。

如果您要自动创建伪造品,可以从tsUnit中获取FakeFactory,它会创建具有一些默认值的伪造版本,您可以选择覆盖这些默认值-在JavaScript中,这是非常简单的事情(此外,不要使用太多的模拟功能,您可以确保自己正在测试行为而不是实施。

FakeFactory的示例用法:

1
2
3
var target = tsUnit.FakeFactory.getFake<RealClass>(RealClass);
var result = target.run();
this.areIdentical(undefined, result);


在Typescript中,可以通过使用sinon.createStubInstance和SinonStubbedInstance类来实现。

例:

1
2
3
let documentRepository: SinonStubbedInstance<DocumentRepository>;

documentRepository = sinon.createStubInstance(DocumentRepository);

现在,您具有使用此类的所有已存根方法的完整的智能感知。

示例安排:

1
2
3
documentRepository.delete.resolves({deletedCount: 1});

documentRepository.update.throws(error);

断言示例:

1
sinon.assert.calledOnce(documentRepository.update);

只有一个地方需要执行类型转换,这就是要进行单元测试的类的初始化。

例:

1
2
3
4
documentsController =
  new DocumentsController(
    userContext,
    documentRepository as unknown as DocumentRepository);

希望这会有所帮助。
有关本文的更多信息。


使用ts-sinon。

它可以让您:

  • 存根对象
  • 存根接口