носорог издевается с синглтоном - PullRequest
1 голос
/ 02 июня 2009

Я использую компонент от третьего лица. Компонент предоставляет единый шаблон для контекста в наше приложение. Я использую на своей стороне этот синглтон, но я хотел бы смоделировать этот объект для моего теста. Есть ли способ сделать издевательство над этим объектом.

Кроме того, конструктор объявляется закрытым.

Ответы [ 2 ]

2 голосов
/ 02 июня 2009

С 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 ... есть библиотека с открытым исходным кодом, которая сгенерирует ваш прокси-класс для вас во время выполнения.

Duck Typing .Net

0 голосов
/ 02 июня 2009

Если сторонний синглтон возвращает интерфейс, а не конкретный класс (это должно быть), то насмешки Rhino смогут его смутить.

Если вы просто хотите заглушить это, посмотрите Rhino mocks 'MockRepository.Stub<IMyInterface>()

...