我正在使用第三方组件。该组件为我们的应用程序提供上下文单例模式。我在这边使用这个单身人士,但我想嘲笑这个对象作为我的测试。有什么办法来完成这个对象的模拟。犀牛与单身人士嘲笑
此外,构造函数被声明为private。
我正在使用第三方组件。该组件为我们的应用程序提供上下文单例模式。我在这边使用这个单身人士,但我想嘲笑这个对象作为我的测试。有什么办法来完成这个对象的模拟。犀牛与单身人士嘲笑
此外,构造函数被声明为private。
随着RhinoMocks你必须有一个接口。如果你真的需要嘲笑这个,那么你必须通过将单例包装到另一个实例化接口的类中来作弊。这个接口基本上是第三方单身类型的所有公共成员的拷贝副本。
该概念与Duck Typing类似,但由于CLR不支持鸭子键入,因此您必须使用代理类。
下面是一个例子:
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();
}
}
瞧!高兴地嘲笑单身人士没有头痛(好吧,那么有点头痛)。你可能认为整个代理类将会是一个痛苦的屁股,但幸运的是,一些好的人会让这个过程更容易一些。整个鸭子键入的东西我刚才提到...有一个开源库,将在运行时为您生成您的代理类。
如果第三方Singleton返回一个接口而不是一个具体的类(它应该),那么Rhino mocks将能够嘲笑它。
如果你只是想存根出来,看看犀牛嘲笑MockRepository.Stub<IMyInterface>()