【发布时间】:2020-05-14 08:49:14
【问题描述】:
经过大量阅读,我发现人们建议在单元测试的方法中模拟每个依赖项。
Should I mock all the dependencies when unit testing?
但是,我有一个创建对象列表(依赖项)并使用这些对象的方法来更改列表的方法。在实际场景中,该方法是将客户端发送的数据负载转换为这些对象。 下面是 Typescript 中的代码实现,但它只是给你一个想法。
import {expect} from 'chai';
import 'mocha';
class Bar {
private val: number;
constructor(val: number) {
this.val = val;
}
isValid(): boolean {
return this.val !== 2;
}
canMergeWith(bar: Bar): boolean {
return this.val === bar.val;
}
}
class BarBuilder {
constructor() {
}
createBars(payload: number[]): Bar[] {
const bars: Bar[] = [];
payload.forEach(p => {
bars.push(new Bar(p));
});
const filtered = this.filterBars(bars);
const merged = this.mergeBars(filtered);
return merged;
}
private filterBars(bars: Bar[]): Bar[] {
return bars.filter(b => b.isValid());
}
private mergeBars(bars: Bar[]): Bar[] {
const merged: Bar[] = [];
bars.forEach((bar, i) => {
if (i > 0) {
const before = bars[i - 1];
if (!bar.canMergeWith(before)) {
merged.push(bar);
}
} else {
merged.push(bar);
}
});
return merged;
}
}
describe('BarBuilder', () => {
it('Should convert payload into valid bars', () => {
const payload = [1, 2, 3, 4, 4, 5, 5];
const barBuilder = new BarBuilder();
const bars = barBuilder.createBars(payload);
expect(bars).to.deep.equal([{val: 1}, {val: 3}, {val: 4}, {val: 5}]);
});
});
目前,测试正在通过。但这违反了我应该模拟类中的每个依赖项的规则。
我应该做以下哪一项:
- 我真的应该模拟 Bar 类以遵守该规则吗?
如果是这样,我发现这样做还有另一个困难。如果我模拟 Bar 类,如何使模拟方法 canMergeWith 和 isValid 根据输入返回 true 或 false?不等于重写类本身吗?
- 我应该重构我的代码吗?
我也在想问题可能在于我的代码不可测试。之前,方法canMergeWith 和isValid 属于BarBuilder。为了便于阅读,我将它们移到了 Bar 中。但是现在,BarBuilder 的单元测试已经不再繁琐了。
- 尽管测试违反了单元测试规则,但仍保持原样。
【问题讨论】:
标签: unit-testing oop language-agnostic