假设您有一个类Foo,类型为Bar的私有成员。您不希望用户知道Foo的实现包含一个Bar,并且您不希望用户能够创建自己的Bar并通过Foo的构造函数,任何其他方法或配置文件传递它。
编辑:Bar也存在问题,因为它访问测试环境控制之外的资源,例如特殊数据库,网络连接或其他进程。
当你还希望能够对Foo进行单元测试时,你会怎么做?依赖注入仍然可能吗?这是否意味着Bar和Foo过于紧密耦合(即使依赖是单向的)并且这种情况从来都不是可接受的?
答案 0 :(得分:5)
如果可以提供帮助,您永远不想隐藏依赖项。
如果是你的代码,你应该通过重新设计Bar
来接受由昂贵的资源产生的对象而不是直接访问昂贵的资源来明确依赖:将数据库访问代码(或其他任何东西)移出Bar
和Foo
,你可以注入测试双打。
如果那不实际(即你正在与别人的课程打交道),Dror's list非常好。
答案 1 :(得分:4)
[免责声明:我的工作时间为Typemock]
您有三种选择:
Isolate.Swap.NextInstance<Bar>.With(fakeBar);
答案 2 :(得分:1)
如果Bar类型只是Foo的一个实现细节,那么你的单元测试永远不必担心创建Bars,因为它们应该只运用Foo的公共接口。
编辑:如果Bar访问外部资源,那么我会使它成为Foo的显式依赖项,然后需要将一个实例传递给Foo的构造函数,然后可以很容易地模拟单元测试。答案 3 :(得分:1)
您的问题不是您需要访问私人会员。这只是一个问题,即所讨论的类并非设计为孤立的。它只允许一个非常具体的用法,即new
一个对象,它会占用昂贵的资源。
即使你成功地攻击了不可测试的设计,你仍然只会进行集成测试。单元测试是关于隔离,这与集成相反。由于该类无法隔离,因此根据定义,您无法对其进行单元测试。
是否有理由将依赖项外部化?这个对象如何免于像其他任何一样被依赖注入?
修改强>:
我当然意识到你可以用一些技巧来隔离它。但是,这些技术绕过公共接口,限制了未来的灵活性,并增加了某人破坏它的可能性(基本上,使私人成员的用处无效)。