Который возражает для насмешки при выполнении TDD

Как Douglas Mayle отметил, это в основном обозначает имя типа. Следовательно, Вам не рекомендовалось бы закончить имена переменной или имена функций с' _t', так как это могло вызвать некоторый беспорядок. А также size_t, стандарт C89 определяет wchar_t, off_t, ptrdiff_t, и вероятно некоторые другие, которых я забыл. Стандарт C99 определяет много дополнительных типов, такой как uintptr_t, intmax_t, int8_t, uint_least16_t, uint_fast32_t, и так далее. Эти новые типы официально определяются в [1 110], но чаще всего Вы будете использовать , который (необычно для стандарта C заголовки) включает . Это () также определяет макросы для использования с printf() и scanf().

, Поскольку Matt Curtis отметил, нет никакого значения для компилятора в суффиксе; это - ориентируемое на пользователя соглашение.

Однако необходимо также отметить, что POSIX определяет много дополнительных имен типов, заканчивающихся в' _t', и резервы суффикс для реализации. Это означает, что, если Вы работаете над связанными с POSIX системами, определение Ваших собственных имен типов с соглашением опрометчиво. Система я продолжаю работать, делала его (больше 20 лет); мы регулярно сбиваемся с толку системами, определяющими типы с тем же именем, как мы определяем.

9
задан balpha 10 February 2010 в 10:54
поделиться

10 ответов

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

Необязательно передавать все объекты в качестве параметров метода. Часто лучше внедрять соавторов в классы с помощью Constructor Injection. Это сохраняет ваши интерфейсы в чистоте, в то время как ваши реализации могут импортировать нужных соавторов.

Допустим, ваша исходная реализация выглядела так:

public class Foo
{
    public Ploeh DoStuff(Fnaah f)
    {
        var bar = new Bar();
        return bar.DoIt(f);
    }
}

Это можно было изменить так:

public class Foo
{
    private readonly IBar bar;

    public Foo(IBar bar)
    {
        this.bar = bar;
    }

    public Ploeh DoStuff(Fnaah f)
    {
        return this.bar.DoIt(f);
    }
}

Обратите внимание, что я изменил bar от экземпляра Bar к экземпляру IBar, тем самым отделяя Foo от конкретной реализации IBar.

7
ответ дан 4 December 2019 в 10:32
поделиться

Я не уверен, какой язык / инструменты вы используете, но способ, которым это можно сделать - rails, - это просто имитировать конструктор, например:

@user = mock_model(User)
User.stub(:create).and_return(@user)

Итак, с этого момента в ваших тестах, если вы вызываете User.create (User - это «класс»), он всегда будет возвращать вашу предопределенную переменную @user, что позволяет вам полностью контролировать, какие данные используются в ваших модульных тестах.

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

0
ответ дан 4 December 2019 в 10:32
поделиться

[Отказ от ответственности: я работаю в Typemock]
Вы есть три варианта, два из которых требуют некоторого рефакторинга:

  1. Передавать все аргументы - как вы уже знаете, вы можете передавать имитирующие / заглушки вместо «реальных» объектов.
  2. Используйте контейнер IoC - реорганизуйте ваш код, чтобы использовать контейнер для захвата объектов из вашего кода, и вы можете заменить их макетами / заглушками.
  3. Используйте Typemock Isolator (.NET), который может подделывать будущие объекты - объекты, экземпляры которых создаются внутри вашего кода из тестового кода . Этот вариант не требует рефакторинга, и если у вас большая база кода, он должен стоить своего кода.

Разработка с учетом тестируемости не всегда является хорошей практикой, особенно с существующим проектом, где вы уже написали код. Так что если вы начинаете с чистого листа или имеете небольшой проект, возможно, можно передавать объекты в качестве аргументов конструктору класса, если у вас не слишком много параметров.
- Если вы используете контейнер IoC.

Если вы не хотите изменять весь существующий код и / или не хотите разрабатывать свой код определенным образом, чтобы сделать его «более тестируемым» (может вызвать некоторую странность на вид кода - используйте Isolator (или аналогичный инструмент) если вы используете Java).

2
ответ дан 4 December 2019 в 10:32
поделиться

Вы должны отдавать предпочтение методам, которые не принимают аргументов, за которыми следует один аргумент, два и, наконец, три . Все, что принимает больше 3, - это запах кода. Либо существует класс, ожидающий обнаружения во всех передаваемых аргументах, либо класс / метод пытается сделать слишком много.

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

0
ответ дан 4 December 2019 в 10:32
поделиться

В какой-то момент вы не собираетесь отказываться от создания одного объекта из другого, но вы должны писать программное обеспечение в соответствии с хорошими принципами проектирования. Например, SRP, DI и т. Д.

Там, где у вас много зависимостей, вы можете найти контейнер IoC, который поможет вам управлять ими всеми.

При работе с унаследованным кодом вам может быть полезно прочитать Майкла Фезера. Эффективно работает с устаревшим кодом . В книге есть много способов протестировать вашу систему.

1
ответ дан 4 December 2019 в 10:32
поделиться

Просто наблюдение: вы говорите о методах, а я предпочитаю говорить о классах.

На этот вопрос нет общего ответа. Иногда действительно важно отделить создание класса от использования.

Учтите:

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

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

2
ответ дан 4 December 2019 в 10:32
поделиться

Первая часть - это немного загруженный вопрос. Это все равно, что спрашивать: «При наезде на пешеходов в моей машине должны ли я держать руль обеими руками?»

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

Однако один из ключевых способов сделать ваш код тестируемым - это использовать IoC (инверсия управления), где зависимости класса (или метода) передаются ему, а не класс, запрашивающий их. Это значительно упрощает тестирование, так как вы можете пройти в mocks.

Итак, краткий ответ - «Да», передайте свои зависимости и посмотрите на хороший компонент внедрения зависимостей . Длинный ответ: «Да, но не делай этого». Фреймворки DI, вероятно, заставят вас передавать зависимости объектам, а не методам, и вы обнаружите, что хотите ограничить эти зависимости - что хорошо.

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

6
ответ дан 4 December 2019 в 10:32
поделиться

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

Используйте mock, если хотите изолировать класс от других. Используйте имитацию, чтобы держать тесты подальше от

  • файловых систем
  • баз данных
  • сетей
  • объекта с непредсказуемым поведением (часы, генератор случайных чисел ...)

Использование объекта отдельно от их построения

2
ответ дан 4 December 2019 в 10:32
поделиться

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

0
ответ дан 4 December 2019 в 10:32
поделиться

Я предпочитаю высмеивать практически все, что находится вокруг объекта, и определять поведение тестируемого объекта в терминах вызовов и ответов от связанных объектов.

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

0
ответ дан 4 December 2019 в 10:32
поделиться
Другие вопросы по тегам:

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