执行单元测试时,最好测试我希望将其硬编码到测试中的文字结果(expect(x).toBe(17)
),还是更好地测试逻辑而不是我特定的模拟数据使用(expect(x).toBe(mockedData.value)
)
第一种方法似乎更安全,因为我确信测试实际上是测试我期望的文字结果,但是第二种方法更灵活,因为它允许我测试逻辑而不是担心模拟数据(我也可以在以后更改而不必重写测试本身)
这两种方法的优点/缺点是什么?在这些情况下,最佳做法是什么?
以下是一个简单的例子:
// MockedData is a very long array of complex objects
// each of them has a property 'value' of type number
import mockedData from 'data.mock';
class ClassToTest {
private data;
constructor(data) {
this.data = data;
}
plusOne(): number {
return this.data.value + 1;
}
}
describe('test', () => {
let instance: ClassToTest;
beforeEach(() => {
instance = new ClassToTest(mockedData[0]);
})
it('plusOne() should return the property "value" plus one', () => {
// Should I write this...
expect(instance.plusOne()).toBe(mockedData[0] + 1);
// ...or this?
expect(instance.plusOne()).toBe(17); // Because I know that mockedData[0].value is 16
})
});
非常感谢!! :)
答案 0 :(得分:1)
在您的测试中,您希望测试您的设备,在您的情况下,这是您的plusOne()
功能内部的逻辑。所以你只想知道函数内部是否有变化。
最危险的路径是使用expect(instance.plusOne()).toBe(17);
,因为如果有人将您的逻辑更改为return this.data.value + 2;
,则只有当问题出现在函数逻辑或mockedData中时,才会从测试中发现。< / p>
使用expect(instance.plusOne()).toBe(mockedData[0] + 1);
的方法不太危险,因为这会告诉您函数中的逻辑是否会发生变化。仍然不是最佳的,因为您依赖外部模拟来运行您不需要的测试。您为什么要依赖外部模拟数据来测试您的设备?
在这里测试单位逻辑的最佳方法是做这样的事情:
describe('test', () => {
let instance: ClassToTest;
const mockedValue = 1;
beforeEach(() => {
instance = new ClassToTest(mockedValue);
})
it('plusOne() should return the property "value" plus one', () => {
expect(instance.plusOne()).toBe(mockedValue + 1);
})
});
然后,您可以为您的服务实施单独的测试,这里您只测试plusOne()
内的逻辑。