Как дразнить статический единичный предмет?

У меня есть количество классов, к которым меня попросили добавить некоторые модульные тесты с Насмешками Носорога и имеющий некоторые проблемы.

Прежде всего я знаю, что RhinoMocks не допускает насмешку Статических участников. Я ищу, какие варианты я имею (помимо использования TypeMock).

Пример класса, который я имею, подобен ниже:

class Example1 : ISomeInterface
{
    private static ISomeInterface _instance;

    private Example1()
    {
        // set properties via private static methods
    }

    static Example1()
    {
        _instance = new Example1();
    }

    public static ISomeInterface Instance() 
    {
        get { return _instance; }
    }

    // Instance properties 

    // Other Instance Properties that represent objects that follow a similar pattern.
}

Таким образом, когда я называю вышеупомянутый класс, он выглядит примерно так...

Example1.Instance.SomeObject.GoDownARabbitHole();

Есть ли способ для меня дразнить SomeObject.GoDownARabbitHole() в этой ситуации или насмешке Случай?

14
задан JamesEggers 12 January 2010 в 17:21
поделиться

4 ответа

Одиночки противоречат Testability, потому что их так трудно изменить. Намного лучше использовать Dependency Injection для введения экземпляра ISomeInterface в классы-потребители:

public class MyClass
{
    private readonly ISomeInterface dependency;

    public MyClass(ISomeInterface dependency)
    {
        if(dependency == null)
        {
            throw new ArgumentNullException("dependency");
        }

        this.dependency = dependency;
    }

    // use this.dependency in other members
}

Заметьте, как Клаус Guard Claus вместе с ключевым словом readonly гарантирует, что экземпляр ISomeInterface будет всегда доступен.

Это позволит вам использовать Rhino Mocks или другую библиотеку динамических имитаций для введения Test Doubles ISomeInterface в классы-потребители.

12
ответ дан 1 December 2019 в 06:23
поделиться

Вот подход с низким прикором, который использует делегат, который может быть установлен изначально и изменен во время выполнения. Это лучше объяснено примером (конкретно, насмешкой TateTime.Now):

http://www.lostechies.com/blogs/jimmy_bogard/archive/2008/11/09/systemtimeTime-versus-isystemclock-dependonds-revisited.aspx

6
ответ дан 1 December 2019 в 06:23
поделиться

Поддержка escape Unicode Asceence:

printf("It's all \u03B5\u03BB\u03BB\u03B7\u03BD\u03B9\u03BA\u03AC to me.\n");

или четные, буквальные символы Unicode:

printf("日本語\n");

(Примечание: не может работать в зависимости от вашего языка; портативная поддержка для разных кодировков займет больше работать, чем это)

-121--833651-

Проверьте впрыск зависимости .

Вы уже начали это, но за трудно проверить классы (статики и т. Д. ...) Вы можете использовать адаптер шаблон дизайна для записи обертки вокруг этого, чтобы проверить код. Используя интерфейс этого адаптера, вы можете затем проверять свой код в изоляции.

Для любых советов по тестированию единиц и дальнейшие проблемы тестирования проверяют блог тестирования Google , в частности, статей Масхо.

Экземпляр

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

1
ответ дан 1 December 2019 в 06:23
поделиться

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

<?php 
function recurse_copy($src,$dst) { 
    $dir = opendir($src); 
    @mkdir($dst); 
    while(false !== ( $file = readdir($dir)) ) { 
        if (( $file != '.' ) && ( $file != '..' )) { 
            if ( is_dir($src . '/' . $file) ) { 
                recurse_copy($src . '/' . $file,$dst . '/' . $file); 
            } 
            else { 
                copy($src . '/' . $file,$dst . '/' . $file); 
            } 
        } 
    } 
    closedir($dir); 
} 
?>
-121--3473510-

Спасибо за ответы. Я чувствую, что каждый ответ был частью ответа. Вот что я искал. Символ

  1. ? является просто кратким для (something 'start) . Таким образом, (a 'start) можно переписать как a? . Таким образом, пример становится:

     b * (abb *) * a?
    

    В питоне мы бы написали:

     p = re.compile (r '^ b * (abb *) * a? $')
    
  2. Прямая трансляция синтаксиса регулярного регулярного выражения в python (т.е. копирование и вставка) не работает, потому что python соответствует самой короткой подстроке (если символы $ или ^ отсутствуют), в то время как теоретические регулярные выражения соответствуют самой длинной начальной подстроке .
    Так, например, если у нас была последовательность:

     s = 'aa'
    

    Наш учебник regex b * (abb *) * a? не будет соответствовать ему, потому что у него есть два а. Однако если скопировать его прямо в python:

     > > p = re.compile (r 'b * (abb *) * a?')
    > > bool (p.match (s))
    Правда
    

    Это происходит потому, что наш регекс соответствует только подстроке «a» нашей последовательности «aa».
    Для того, чтобы сказать Питону, чтобы сделать совпадение в целом ряде мы должны сказать ему, где начало и конец последовательности, с ^ и $ соответственно:

     > > p = re.compile (r '^ b * (abb *) * a? $')
    > > bool (p.match (s))
    Ложный
    

    Обратите внимание, что python regex match () совпадает с началом последовательностей, поэтому он автоматически принимает ^ в начале. Однако функция search () не выполняет, и поэтому мы сохраняем ^ .
    Так например:

     > > s = 'aa'
    > > p = re.compile (r 'b * (abb *) * a? $')
    > > bool (p.match (s))
    Ложь # Правильно
    > > bool (p.search (s))
    True # Неверно - поиск проигнорировал первый «» а
    
-121--4594708-

Можно имитировать интерфейс ISomeInterface. Затем выполните рефакторинг кода, который использует его для ввода зависимостей, чтобы получить ссылку на одиночный объект. Я сталкивался с этой проблемой много раз в нашем коде и мне нравится это решение лучше всего.

Например:

public class UseTheSingleton
{
    private ISomeInterface myX;

    public UseTheSingleton(ISomeInterface x)
    {
        myX = x;
    }

    public void SomeMethod()
    {
        myX.
    }
}

Тогда...

UseTheSingleton useIt = UseTheSingleton(Example1.Instance);
1
ответ дан 1 December 2019 в 06:23
поделиться
Другие вопросы по тегам:

Похожие вопросы: