2009-06-02 2 views
1

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

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

ответ

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(); 
    } 
} 

Voila! К счастью, насмехался синглтон без головной боли (хорошо, так немного головная боль). Вероятно, вы думаете, что весь класс Proxy станет болью в прикладе, но, к счастью, некоторые хорошие люди сделали это немного легче. Вся информация о Duck Typing, о которой я упоминал ранее ... есть библиотека с открытым исходным кодом, которая будет генерировать ваш прокси-класс для вас во время выполнения.

Duck Typing .Net

0

Если третье лицо Singleton возвращает интерфейс, а не конкретный класс (он должен), то Rhino mocks сможет издеваться над ним.

Если вы просто хотите, чтобы окурок его, проверить Rhino издевается MockRepository.Stub<IMyInterface>()