我的程序中有一个静态类。在静态构造函数中,我创建了服务实例。服务代理是单身人士。
我必须为这个类编写单元测试,当然我想要隔离这个服务。 我该怎么办?
在我的项目中,我们使用Rhino.Mocks。
答案 0 :(得分:3)
class MyClass()
{
public MyClass()
{
var myService = StaticFoo.MyServiceInstance;
}
}
这相当于在本地创建一个具体的类实例,因为知道“如何到达”您的Singleton是您的类实现的一部分。你需要做的就是删除这些知识并注入这种依赖,就像你在非单例上注入其他依赖一样。最直接的方式是构造函数注入:
class MyClass()
{
public MyClass(IService myService)
{
//..
}
}
另一个需要的部分是确保服务中的所有接口方法/属性都定义为虚拟或定义服务实现的接口或抽象基类,并定义类MyClass
正在使用的所有操作这项服务。这是必需的,因为大多数单元测试框架(包括Rhino-Mocks)只能模拟虚拟方法/属性。
我见过的另一种选择,但个人并不喜欢,在您的Singleton中引入一个setter,这样您就可以用单元测试所需的模拟对象“交换”具体类。此setter仅用于单元测试,可以标记为internal,因此程序集外部的类无权访问。然后,您可以使用InternalsVisibleTo
属性为单元测试程序集创建一个特殊异常,以便它可以查看和使用setter。
这种方法的主要优点是,它需要较少的重构才能获得可测试的解决方案,但代价是“污染”静态Singleton支架的界面。因为在大多数情况下,首先不需要单身人士,我会考虑首先重构构造函数。
答案 1 :(得分:1)
您需要在您的类上拥有一个接受该服务实例的公共初始化方法。然后,您可以使用初始化方法注入模拟对象。