我正在使用来自第三方的组件。该组件为我们的应用程序中的上下文提供单例模式。我正在使用这个单身人士,但我想模仿这个对象进行测试。有没有办法在这个对象上完成模拟。
此外,构造函数被声明为private。
答案 0 :(得分:2)
使用RhinoMocks,您必须拥有一个界面。如果你真的需要模拟这个,那么你将不得不通过将单例包装在另一个实例化接口的类中来作弊。该界面基本上需要是第三方单身人士类型的所有公共成员的副本。
这个概念类似于Duck Typing,但由于CLR不支持Duck Typing,你必须使用代理类。
以下是一个例子:
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();
}
}
瞧!高兴地嘲笑单身人士没有头痛(好吧,所以有点头疼)。您可能认为整个Proxy类将会成为一个痛苦的屁股,但幸运的是,一些优秀的人已经让这更容易了。我之前提到的整个Duck Typing的东西......有一个开源库,可以在运行时为你生成代理类。
答案 1 :(得分:0)
如果第三方Singleton返回一个接口而不是一个具体类(它应该),那么Rhino模拟将能够模拟它。
如果您只想将其删除,请查看Rhino mocks'MockRepository.Stub<IMyInterface>()