应该如何使用 tdd 重复行为进行测试
How should test using tdd repeated behaviors
我有下一个代码,我做了一个测试,但现在我遇到了一个难题,严格来说,使用 tdd 来添加
"this.loadCounter('anotherReq', 'anotherError', differentCallback);"
我必须回复测试只是为了测试行为,但我不确定这是否有必要。
class Statistic extends PureComponent<Props, State> {
state = {
};
componentDidMount() {
this.loadCounter('suggestedReqCount', 'hasSuggestedReqsErrors', getCountSuggestedReqs);
this.loadCounter('anotherReq', 'anotherError', differentCallback);
}
loadCounter = async (
stateCounterKey: string, stateCounterErrorKey: string, loaderFunction: Function) => {
try {
const count = await loaderFunction();
this.setState({
[stateCounterKey]: count,
});
} catch (ex) {
this.setState({
[stateCounterErrorKey]: true,
});
}
}
}
这是我的测试
test('Should set state with suggested requirement count', async () => {
const wrapper = mount(
<Statistic
intl={{
formatMessage: jest.fn(),
}}
/>,
);
wrapper.update();
await getCountSuggestedReqs();
expect(wrapper.state().suggestedReqCount).toBe(5);
});
test('Should on fail load suggested reqs update state', async () => {
getCountSuggestedReqs.mockReturnValueOnce(Promise.reject('Error creado'));
const wrapper = mount(
<Statistic
intl={{
formatMessage: jest.fn(),
}}
/>,
);
wrapper.update();
await getCountSuggestedReqs();
expect(wrapper.state().hasSuggestedReqsErrors).toBe(true);
});
TDD 的第一条规则是我们不能在测试失败之前编写任何生产代码。
仅此一项就意味着,如果您想添加生产代码,则必须编写需要它的测试。
也就是说,在某些情况下我不会编写单元测试并让更大的测试获取该功能,例如在简单委托的情况下 - 代码不执行任何逻辑,只是传递相同的参数到另一个功能,所以没有什么真正要测试的,从外面测试接线。
然而,在这种情况下,在我看来,您调用该函数两次是为了获得不同的信息。
您可以扩展现有测试以包含新数据,但我不喜欢该选项。我宁愿保留现有测试并为新功能添加新测试。请注意 "As the tests become more specific, the code becomes more generic",此处也是如此。也许当第三次调用 loadCounter
时,您需要重构代码以使其更通用,但此时我只添加第二个单元测试。
综上所述,您绝对应该将逻辑代码和组件代码分开。这个单元测试没有理由成为酶测试。 componentDidMount
中的代码可以很容易地重构为一个可以通过简单的 ol' 测试进行单元测试的函数。
我有下一个代码,我做了一个测试,但现在我遇到了一个难题,严格来说,使用 tdd 来添加
"this.loadCounter('anotherReq', 'anotherError', differentCallback);"
我必须回复测试只是为了测试行为,但我不确定这是否有必要。
class Statistic extends PureComponent<Props, State> {
state = {
};
componentDidMount() {
this.loadCounter('suggestedReqCount', 'hasSuggestedReqsErrors', getCountSuggestedReqs);
this.loadCounter('anotherReq', 'anotherError', differentCallback);
}
loadCounter = async (
stateCounterKey: string, stateCounterErrorKey: string, loaderFunction: Function) => {
try {
const count = await loaderFunction();
this.setState({
[stateCounterKey]: count,
});
} catch (ex) {
this.setState({
[stateCounterErrorKey]: true,
});
}
}
}
这是我的测试
test('Should set state with suggested requirement count', async () => {
const wrapper = mount(
<Statistic
intl={{
formatMessage: jest.fn(),
}}
/>,
);
wrapper.update();
await getCountSuggestedReqs();
expect(wrapper.state().suggestedReqCount).toBe(5);
});
test('Should on fail load suggested reqs update state', async () => {
getCountSuggestedReqs.mockReturnValueOnce(Promise.reject('Error creado'));
const wrapper = mount(
<Statistic
intl={{
formatMessage: jest.fn(),
}}
/>,
);
wrapper.update();
await getCountSuggestedReqs();
expect(wrapper.state().hasSuggestedReqsErrors).toBe(true);
});
TDD 的第一条规则是我们不能在测试失败之前编写任何生产代码。
仅此一项就意味着,如果您想添加生产代码,则必须编写需要它的测试。
也就是说,在某些情况下我不会编写单元测试并让更大的测试获取该功能,例如在简单委托的情况下 - 代码不执行任何逻辑,只是传递相同的参数到另一个功能,所以没有什么真正要测试的,从外面测试接线。
然而,在这种情况下,在我看来,您调用该函数两次是为了获得不同的信息。
您可以扩展现有测试以包含新数据,但我不喜欢该选项。我宁愿保留现有测试并为新功能添加新测试。请注意 "As the tests become more specific, the code becomes more generic",此处也是如此。也许当第三次调用 loadCounter
时,您需要重构代码以使其更通用,但此时我只添加第二个单元测试。
综上所述,您绝对应该将逻辑代码和组件代码分开。这个单元测试没有理由成为酶测试。 componentDidMount
中的代码可以很容易地重构为一个可以通过简单的 ol' 测试进行单元测试的函数。