如何 'properly' 在打字稿中编写测试

how to 'properly' write tests in typescript

我真的很喜欢 tdd,想学习一门新语言,所以选择了 typescript。不幸的是,我正在努力按照我想要的方式编写测试。

说我正在测试以下 class:

class Container {

    private numbers: number[];

    constructor(){
            this.numbers = [];
    }

    addNumber(numberToAdd: number) : void {
        //implementation
    }

    removeNumber(numberToRemove: number) : void {
        //implementation
    }

    getNumbers(): number[] {
        //implementation
    }
}

我的直觉是做这样的事情:

describe( "container", () => {
    let sut: Container;
    beforeEach(() => sut = new Container());

    describe( "add number", () => {
        let number1 = 1;
        let numbers = sut.getNumbers();

        test( "number should be added", () => {
             numbers.should.contain(number1);
        });  

        test("exactly one number should have been added", () => {
             numbers.length.should.be(0);
        });     
    });

    describe( "remove number", () => {
        let addedNumber = 2;
        sut.addNumber(addedNumber);
        sut.removeNumber(addedNumber);
        let numbers = sut.getNumbers();

        test( "added number should be removed", () => {
            numbers.length.should.be(0);
        });
    });
});

jest 无法正确执行此操作。容器在每个测试语句之前都没有实例化——我不确定为什么不,也许它不喜欢我的嵌套描述语句?显然我可以在每个描述中单独实例化 sut,但我会重复代码...

你如何用 typescript 编写测试?你有什么建议吗?如果您可以分享您的最佳实践,那就太好了。也许开玩笑不是这项工作的正确工具?

我也想知道是否有人愿意分享一个 link 一个开源项目,它是如何在打字稿中进行测试的一个很好的例子

您的问题实际上是关于 jest,而不是关于 TypeScript。

嵌套 describe() 调用中的语句在调用 beforeEach() 之前执行。因此你得到 undefined.

describe( "container", () => {
    let sut: Container;
    beforeEach(() => sut = new Container());

    describe( "add number", () => {
        let number1 = 1;
        let numbers = sut.getNumbers();
    });

    describe( "remove number", () => {
        let addedNumber = 2;
        sut.addNumber(addedNumber);
        sut.removeNumber(addedNumber);
        let numbers = sut.getNumbers();
    });
});

如@JB Nizet 所述,您应该通过测试或在它们自己的 beforeEach() 调用中移动这些语句。

IMO,我倾向于避免 beforeAll()beforeEach()。它使测试更神奇,更难理解。

我建议创建您自己的 setup/teardown 方法并在测试中调用它们。例如:

function setup() {
  return new Container();
}

describe( "container", () => {
    describe( "remove number", () => {
        test( "added number should be removed", () => {
            const sut = setup()

            sut.addNumber(2);
            sut.removeNumber(2);
            const actual = sut.getNumbers();

            actual.length.should.be(0);
        });
    });
});