Почему нам нужны насмешливые рамки?

17

Я работал с кодом, на котором был написан тест NUnit. Но я никогда не работал с насмешливыми рамками. Кто они такие? Я понимаю инъекцию зависимостей и то, как это помогает улучшить тестируемость. Я имею в виду, что все зависимости можно издеваться во время модульного тестирования. Но почему же нам нужны насмешливые рамки? Разве мы не можем просто создавать макетные объекты и предоставлять зависимости. Я что-то упустил? Спасибо.

    
задан Sandbox 11.11.2009 в 19:14
источник

11 ответов

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

Здесь у вас есть пример:

var extension = MockRepository
    .GenerateMock<IContextExtension<StandardContext>>();
  var ctx = new StandardContext();
  ctx.AddExtension(extension);
  extension.AssertWasCalled(
    e=>e.Attach(null), 
    o=>o.Constraints(Is.Equal(ctx)));

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

    
ответ дан flq 11.11.2009 в 19:18
источник
11

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

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

    
ответ дан Justin Niessner 11.11.2009 в 19:17
источник
7

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

    
ответ дан Rex M 11.11.2009 в 19:18
источник
3

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

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

Откажитесь от Rhino Mocks для примера того, насколько мощным может быть насмешка.

    
ответ дан manu08 11.11.2009 в 19:18
источник
3

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

Они полезны по нескольким причинам:

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

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

  • Вы можете создать mock до , вы создаете реальный объект, чтобы уточнить его интерфейс. Это полезно в тестовом развитии.

ответ дан Frank Krueger 11.11.2009 в 19:19
источник
2

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

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

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

    
ответ дан chills42 11.11.2009 в 19:16
источник
  • Некоторые издевательские рамки идут немного дальше, делая все это вручную, как издевательская статика. –  Chris Missal 14.11.2009 в 20:03
1

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

    
ответ дан mxmissile 11.11.2009 в 19:17
источник
1

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

Например, если у меня есть класс A, содержащий бизнес-правила и логику, которые я хочу проверить, но этот класс A зависит от классов доступа к данным, других бизнес-классов, даже классов u / i и т. д., эти другие классы может быть издевательством, чтобы выполнить определенным образом (или совсем не в случае слабого поведения), чтобы проверить логику в вашем классе А на основе любого воображаемого способа, который эти другие классы могли бы вести себя в производственной среде.

Чтобы дать более глубокий пример, предположим, что ваш класс A вызывает метод в классе доступа к данным, например

public bool IsOrderOnHold(int orderNumber) {}

, тогда макет этого класса доступа к данным может быть настроен для возврата true каждый раз или для возврата false каждый раз, чтобы проверить, как ваш класс A отвечает на такие обстоятельства.

    
ответ дан user74754 21.04.2010 в 20:57
источник
  • хорошо сказано. Издевательствовать позволяет переоценить поведение. –  j2emanue 22.04.2015 в 17:54
1

Я бы сказал, что нет. Написание тестовых удвоений не является большой задачей в 9 раз из 10. В большинстве случаев это делается почти полностью автоматически, просто попросив resharper реализовать интерфейс для вас, а затем просто добавьте незначительные детали, необходимые для этого двойника (потому что вы не делают кучу логики и создают эти сложные сложные двойные тесты, правильно? Правильно?)

«Но почему я хочу, чтобы мой тестовый проект раздулся с кучей тестовых удвоений», - спросите вы. Ну, не стоит. принцип DRY также подходит для тестов. Создайте хорошие тестовые двойки, которые можно использовать повторно и иметь описательные имена. Это делает ваши тесты более читабельными.

Одна вещь, которую он делает, сложнее - использовать двойные тесты. Я склонен соглашаться с Роем Ошеровом и дядей Бобом, вы действительно не хотите, чтобы часто создавали макет с некоторой специальной конфигурацией. Это само по себе дизайнерский запах. Используя фреймворк, можно легко просто использовать тестовые двойники с замысловатой логикой почти в каждом тесте, и в конце концов вы обнаружите, что вы действительно не протестировали ваш производственный код, вы просто проверили чудовищный беспорядочный беспорядок франкенштейнов из mocks, содержащий издевательств, содержащих больше насмешек. Вы никогда не «случайно» сделаете это, если напишете свои собственные двойники.

Конечно, кто-то укажет, что есть моменты, когда вы «имеете» использовать фреймворк, а не делать это было бы просто глупо. Конечно, есть такие случаи. Но у вас, вероятно, нет такого случая. Большинство людей этого не делают, и только для небольшой части кода, или сам код действительно плохой.

Я бы рекомендовал всем (ИСПЫТАННО новичку) держаться подальше от фреймворков и узнать, как обойтись без них, а потом, когда они почувствуют, что им действительно нужно, они могут использовать любую инфраструктуру, которая, по их мнению, является наиболее подходящей, но к тому времени это будет осознанное намерение, и они будут гораздо менее склонны злоупотреблять каркасом, чтобы создать плохой код.

    
ответ дан kai 06.10.2015 в 23:38
источник
0

Хорошо насмешливые рамки делают мою жизнь намного проще и менее утомительной, поэтому я могу потратить время на написание кода. Возьмем, к примеру, Mockito (в мире Java)

 //mock creation
 List mockedList = mock(List.class);

 //using mock object
 mockedList.add("one");
 mockedList.clear();

 //verification
 verify(mockedList).add("one");
 verify(mockedList).clear();

 //stubbing using built-in anyInt() argument matcher
 when(mockedList.get(anyInt())).thenReturn("element");

 //stubbing using hamcrest (let's say isValid() returns your own hamcrest matcher):
 when(mockedList.contains(argThat(isValid()))).thenReturn("element");

 //following prints "element"
 System.out.println(mockedList.get(999));

Хотя это надуманный пример, если вы замените List.class на MyComplex.class , тогда становится очевидным значение наличия насмешливой структуры. Вы можете написать свой собственный или обойтись, но зачем вам идти по этому маршруту.

    
ответ дан non sequitor 11.11.2009 в 19:26
источник
0

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

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

    
ответ дан Hamish Smith 11.11.2009 в 19:29
источник