2009-11-02 3 views
3

У меня есть Singleton, доступ к которому в моем классе через статическое свойство, как это: OtherClassNotBeingTested.Instance.SomeInstanceMethod()Rhino Mocks - Заглушка одноплодной

Я хотел бы, чтобы проверить мой класс с вне делает один из этих объектов. Есть ли способ для RhinoMocks вернуть заглушку, когда вызывается геттер для статического свойства Instance?

Чтобы понятнее, вот код для свойства экземпляра:

/// <summary> 
    /// Make a property to allow the OtherClassNotBeingTested class 
    /// to be a singleton 
    /// </summary> 
    public static OtherClassNotBeingTested Instance 
    { 
     get 
     { 
      // Check that the instance is null 
      // NOTE: COMMENTS BELOW HAVE SHOWN THIS TO BE BAD CODE. DO NOT COPY 
      if (mInstance == null) 
      { 
       // Lock the object 
       lock (mSyncRoot) 
       { 
        // Check to make sure its null 
        if (mInstance == null) 
        { 
         mInstance = new OtherClassNotBeingTested(); 
        } 
       } 
      } 

      // Return the non-null instance of Singleton 
      return mInstance; 
     } 
    } 

Update: Вот как я в конечном итоге ее определения:

class ClassBeingTested 
{ 
    public ClassBeingTested(IGuiInterface iGui):this(iGui, Control.Instance) 
    { 

    } 

    public ClassBeingTested(IGuiInterface iGui, IControl control) 
    { 
     mControl = control; 

     //Real Constructor here 
    } 
} 

Мои модульные тесты называют второй конструктор. Фактический код вызывает первый конструктор. Код в классе использует локальное поле mControl вместо синглтона. (Я думаю, что это называется инъекцией зависимостей.)

Я также реорганизовал Singleton согласно Тони Пони.

ответ

4

Я надеюсь, что ваша переменная mInstance объявлена ​​изменчивой, в противном случае ваша реализация DCL будет нарушена. Серьезно, вам действительно нужен этот уровень лени? Я лично рекомендовал некоторые из simpler patterns available.

Однако, когда дело доходит до насмешек - нет, вы не можете издеваться над статическими вызовами с RhinoMocks. Есть некоторые доступные инструменты, которые позволяют это, например, Typemock, но лично я бы реорганизовал приложение, чтобы быть более проверяемым в первую очередь.

Другой вариант - иметь «обманный» синглтон, в котором вы можете установить значение свойства singleton в тестовом примере. Если вы вернете свойство вместо интерфейса singleton, вы можете заменить реальный синглтон макетом.

+0

Эта конструкция копируется и вставлена. Я собираюсь изменить его, чтобы следовать шаблону в вашей ссылке. Я думаю, что у меня будет переменная в классе, которую будет назначать singleton. Таким образом, я могу издеваться над этим. – Vaccano

+3

Я, например, приветствую нашего Пони-Повелителя. –

+0

Ответ Тони Пони правильный. Я хотел бы добавить, что проблемы с тестируемостью являются одной из причин того, что шаблон Singleton выпадает из-за неприязни. Возможно, вы захотите рассмотреть инфраструктуру контейнера DI/IoC (зависимость от инжекции/инверсии управления), такую ​​как [Unity] (http://www.codeplex.com/unity) или [StructureMap] (http: //structuremap.sourceforge. net/Default.htm) - они могут создавать обычные статические объекты с помощью Singleton-like lifespans. – TrueWill

4

Несмотря на другие слухи вы можете издеваться одиночек, увидеть мой ответ:

How to Mock a Static Singleton?

В данном случае это даже проще, так как не существует статический конструктор. Если ваш синглтон уже реализует интерфейс, нет необходимости изменять ваш продуктивный код.