如何使类更具可测试性
本文关键字:可测试性 何使类 | 更新日期: 2023-09-27 18:08:18
我有这个:
class FooGenerator:IFooGenerator {
private object _generated;
public void Generate() {
// Generating
GenerateSmallPart();
GenerateOtherSmallPart();
GenerateTinyPart();
// A lot similar
}
private void GenerateSmallPart() {
//add small part to _generated
}
private void GenerateOtherSmallPart() {
//add small part to _generated
}
private void GenerateTinyPart() {
//add small part to _generated
}
}
internal interface IFooGenerator {
void Generate();
}
在我的应用程序中,我只使用IFooGenerator
通过IoC,但我想测试所有这些子方法。
正如我在这里发现的,一种选择是提取具有所有子方法的类。但我为什么要这么做。仅在FooGenerator
中使用
你有什么建议我怎样才能使我的类更可测试吗?
我将与你分享我通常是如何处理这种情况的。如果我发现由于某种原因(比如很难存根输入参数来测试所有代码流),我想测试一些私有方法——这通常意味着我的类的复杂性很高,我需要重构我的代码。在你的情况下(我不知道你的方法在做什么),你可以使用这样的东西:
interface IPartGenerator
{
void GeneratePart();
}
class SmallPartGenerator : IPartGenerator
{
void GeneratePart();
}
class OtherSmallPartGenerator : IPartGenerator
{
void GeneratePart();
}
class TinyPartGenerator : IPartGenerator
{
void GeneratePart();
}
class FooGenerator:IFooGenerator
{
private IPartGenerator[] partGenerators = new IPartGenerator[]
{
new SmallPartGenerator(),
new OtherSmallPartGenerator(),
new TinyPartGenerator ()
}
public void Generate()
{
foreach (var partGenerator in partGenerators)
{
partGenerator.GeneratePart();
}
}
}
现在您可以分别测试每个部件生成器。
谁是客户?
许多人(Roy Osherove, Michael Feathers)认为测试客户端与接口或服务客户端一样有效。
考虑到这一点,我认为稍微违反封装原则是可以的,通过将一些私有方法设置为公共来打开可测试的接缝。
你的类不是做一件事,而是做几件事——每件事都封装在一个私有方法中。这违反了单一责任原则(SRP)。根据SRP,一个类应该只做一件事。
Neil Thompson建议你应该把私有方法变成公共方法。这至少使它们可以被单元测试访问,但是它们仍然是违反SRP的。如果你的班级有很多不同的东西,入会通常是复杂的;您必须在满足所有方法需求的状态下创建类,尽管您只想测试一个小角落。这对可测试性没有任何好处。
在此之后,outcoldman的答案是一个更健全的设计。他的代码没有违反SRP