С 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();
}
}
Voila! К счастью, насмехался синглтон без головной боли (хорошо, так немного головная боль). Вероятно, вы думаете, что весь класс Proxy станет болью в прикладе, но, к счастью, некоторые хорошие люди сделали это немного легче. Вся информация о Duck Typing, о которой я упоминал ранее ... есть библиотека с открытым исходным кодом, которая будет генерировать ваш прокси-класс для вас во время выполнения.
Duck Typing .Net