.net 犀牛和独生子
我正在使用来自第三方的组件。该组件为应用程序中的上下文提供了一个单例模式。我正在使用这个单例,但我想模拟这个对象进行测试。有没有办法在这个对象上完成模拟.net 犀牛和独生子,.net,singleton,rhino-mocks,.net,Singleton,Rhino Mocks,我正在使用来自第三方的组件。该组件为应用程序中的上下文提供了一个单例模式。我正在使用这个单例,但我想模拟这个对象进行测试。有没有办法在这个对象上完成模拟 此外,构造函数被声明为私有的。如果第三方Singleton返回一个接口而不是一个具体的类(它应该返回),那么Rhino mocks将能够模拟它 如果您只想将其存根,请查看Rhino mocks的MockRepository.stub()使用Rhinomock,您必须有一个接口。如果您真的需要模拟这个,那么您必须通过将单例包装到另一个实例化接口的
此外,构造函数被声明为私有的。如果第三方Singleton返回一个接口而不是一个具体的类(它应该返回),那么Rhino mocks将能够模拟它
如果您只想将其存根,请查看Rhino mocks的
MockRepository.stub()
使用Rhinomock,您必须有一个接口。如果您真的需要模拟这个,那么您必须通过将单例包装到另一个实例化接口的类中来进行一些欺骗。该接口基本上需要是第三方singleton类型上所有公共成员的副本
这个概念类似于,但是由于CLR不支持Duck类型,所以必须使用代理类
以下是一个例子:
public interface ISingleton
{
void SomePublicMethod();
Int32 SomePublicProperty{ get; set; }
}
public class SingletonProxy: ISingleton
{
private ThirdPartySingleton _singleton = StaticType.GetSingleton(); // ???
public void SomePublicMethod()
{
_singleton.SomePublicMethod();
}
public Int32 SomePublicProperty
{
get{ return _singleton.SomePublicProperty; }
set{ _singleton.SomePublicProperty = value; }
}
}
因此,无论您在哪种类型中使用它,都可以将其作为服务依赖项传入,如下所示:
public class TypeThatUsesSingleton
{
private ISingleton _singleton;
public TypeThatUsesSingleton([HopefullySomeDependencyInjectionAttributeHere] ISingleton singleton)
{
_singleton = singleton;
}
public void DoStuff()
{
_singleton.SomePublicMethod();
}
}
现在,您应该能够在测试中愉快地模拟类,并将其作为依赖项传递,以便让您的单元测试顺利进行:
[Test]
public void ShouldAssertSomeBehavior()
{
var repo = new MockRepository();
var singleton = repo.DynamicMock<ISingleton>();
var sut = new TypeThatUsesSingleton(singleton);
using(repo.Record())
{
singleton.SomePublicMethod();
}
using(repo.Playback())
{
sut.DoStuff();
}
}
[测试]
public void ShouldAssertSomeBehavior()
{
var repo=new MockRepository();
var singleton=repo.DynamicMock();
var sut=使用单体(单体)的新类型;
使用(repo.Record())
{
singleton.SomePublicMethod();
}
使用(repo.Playback())
{
sut.DoStuff();
}
}
瞧!开心地嘲笑单身汉而不头痛(好吧,有点头痛)。您可能会认为整个代理类将是一个令人头疼的问题,但幸运的是,一些优秀的人已经让这变得简单了一些。我之前提到的鸭子打字的事情。。。有一个开源库将在运行时为您生成代理类