我正在使用第三方組件。該組件爲我們的應用程序提供上下文單例模式。我在這邊使用這個單身人士,但我想嘲笑這個對象作爲我的測試。有什麼辦法來完成這個對象的模擬。犀牛與單身人士嘲笑
此外,構造函數被聲明爲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>()