首先我先介绍一下实现,而不依赖注入(这将打破依赖倒置原则):依赖注入和具体的依赖实现
public class MyValidator
{
private readonly IChecksumGenerator _checksumGenerator;
public MyValidator()
{
_checksumGenerator = new MyChecksumGenerator();
}
...
}
为了使该代码可测试让利注入IChecksumGenerator:
public class MyValidator
{
private readonly IChecksumGenerator _checksumGenerator;
public MyValidator(IChecksumGenerator checksumGenerator)
{
_checksumGenerator = checksumGenerator;
}
...
}
现在如果需要,我们可以轻松测试MyValidator和存根checksumGenerator。但是,MyValidator实现在算法上与特定的IChecksumGenerator实现耦合(它不会与任何其他实现一起使用)。因此,一些问题出现:
- 介绍
- 我们破坏封装为MyValidator(耦合MyChecksumGenerator)的私人实现细节的可能性,不正确IChecksumGenerator将被注入(例如,因为IoC容器配置错误)变外部类
我来到了最好的解决方案是:
public class MyValidator
{
private readonly IChecksumGenerator _checksumGenerator;
public MyValidator()
{
_checksumGenerator = new MyChecksumGenerator;
}
internal MyValidator(IChecksumValidator checksumValidator)
{
_checksumValidator = checksumValidator;
}
...
}
他为了测试目的,我引入了特殊的构造函数(所以我可以在测试中将IChecksumValidator存根),但是公共构造函数创建了它所耦合的实现(所以封装没有被破坏)。为测试目的创建一些代码有点难看,但在这种情况下看起来有意义。
你会如何解决这个问题?
如果MyValidator仅适用于IChecksumGenerator的一个特定实现,那么如何将其替换为测试双?无论如何,你会违反LSP ... – 2011-04-26 08:12:51
@Mark:关于LSP的好处。请制定它作为答案。但是我没有得到关于测试双打的意见 – SiberianGuy 2011-04-26 09:01:23
@ldsa:添加了一个答案。 – 2011-04-26 09:28:40