Ваш вопрос касался того, чем фреймворк MS Fakes отличается от NMock, и, похоже, другие ответы решили некоторые из них, но вот еще немного информации о том, чем они одинаковы и чем они отличаются. NMock также похож на RhinoMocks и Moq, поэтому я объединяю их в группу NMock.
Я сразу вижу 3 основных различия между NMock / RhinoMocks / Moq и MS Fakes Framework:
Платформа MS fakes использует сгенерированный код, как и средства доступа в предыдущих версиях Visual Studio, вместо универсальных типов. Если вы хотите использовать фальшивую платформу для зависимости, вы добавляете сборку, которая содержит зависимость, к ссылкам тестового проекта, а затем щелкаете ее правой кнопкой мыши, чтобы сгенерировать тестовые дубли (заглушки или прокладки). Затем, когда вы тестируете, вы фактически вместо этого используете эти сгенерированные классы. NMock использует дженерики для выполнения того же самого (т.е. IStudentRepository studentRepository = mocks.NewMock<IStudentRepository>()
). На мой взгляд, фреймворк MS Fakes препятствует навигации по коду и рефакторингу изнутри тестов, поскольку вы фактически работаете со сгенерированным классом, а не с вашим реальным интерфейсом.
Фреймворк MS fakes предоставляет заглушки и родинки (прокладки), тогда как NMock, RhinoMocks и Moq предоставляют заглушки и макеты . Я действительно не понимаю решения MS не включать моки, и я лично не поклонник родинок по причинам, описанным ниже.
С помощью фреймворка MS fakes вы предоставляете альтернативную реализацию методов, которые хотите заглушить. В этих альтернативных реализациях вы можете указать возвращаемые значения и отслеживать информацию о том, как и был ли вызван метод. С помощью NMock, RhinoMocks и Moq вы создаете фиктивный объект, а затем используете этот объект для указания заглушенных возвращаемых значений или для отслеживания взаимодействий (независимо от того, вызывались ли методы и как). Я считаю, что подход подделок MS более сложен и менее выразителен.
Чтобы прояснить разницу в том, что предоставляют фреймворки: NMock, RhinoMocks и Moq предоставляют два типа тестовых двойников (заглушки и имитаторы). Фреймворк подделок содержит заглушки и родинки (они их называют прокладками) и, к сожалению, не включает имитацию. Чтобы понять различия и сходства между NMock и MS Fakes, полезно понять, что это за разные типы тестовых двойников:
Заглушки: заглушки используются, когда вам нужно предоставить значения для методов или свойств, которые будут запрашиваться у ваших тестовых двойников тестируемым методом. Например, когда мой тестируемый метод вызывает метод DoesStudentExist () тестового двойника IStudentRepository, я хочу, чтобы он возвращал true.
Идея заглушек в подделках NMock и MS одинакова, но с NMock вы должны сделать что-то вроде этого:
Stub.On(mockStudentRepository).Method("DoesStudentExist").Will(Return.Value(true));
А с MSFakes вы бы сделали что-то вроде этого:
IStudentRepository studentRepository = new DataAccess.Fakes.StubIStudentRepository() // Generated by Fakes.
{
DoesStudentExistInt32 = (studentId) => { return new Student(); }
};
Обратите внимание, что в примере MS Fakes вы создаете совершенно новую реализацию для метода DoesStudentExist (обратите внимание, что он называется DoesStudentExistInt32, потому что фреймворк фейков добавляет типы данных параметров к именам методов, когда он генерирует объекты-заглушки, я думаю, что это затемняет ясность тесты). Честно говоря, реализация NMock также вызывает у меня ошибки, потому что она использует строку для идентификации имени метода. (Простите меня, если я неправильно понял, как предполагается использовать NMock.) Этот подход действительно препятствует рефакторингу, и по этой причине я настоятельно рекомендую RhinoMocks или Moq вместо NMock.
Моки: Моки используются для проверки взаимодействия между тестируемым методом и его зависимостями. С NMock вы делаете это, устанавливая ожидания, подобные этому:
Expect.Once.On(mockStudentRepository).Method("Find").With(123);
Это еще одна причина, по которой я предпочитаю RhinoMocks и Moq NMock, NMock использует более старый стиль ожидания, тогда как RhinoMocks и Moq поддерживают подход Arrange / Act / Assert, где вы указываете ожидаемые взаимодействия как утверждения в конце теста, как это :
stubStudentRepository.AssertWasCalled( x => x.Find(123));
Опять же, обратите внимание, что RhinoMocks использует лямбда вместо строки для идентификации метода. Фреймворк ms fakes вообще не предоставляет имеков. Это означает, что в ваших зарезервированных реализациях (см. Описание заглушек выше) вы должны установить переменные, которые, как вы позже убедитесь, были установлены правильно. Это будет выглядеть примерно так:
bool wasFindCalled = false;
IStudentRepository studentRepository = new DataAccess.Fakes.StubIStudentRepository()
{
DoesStudentExistInt32 = (studentId) =>
{
wasFindCalled = true;
return new Student();
}
};
classUnderTest.MethodUnderTest();
Assert.IsTrue(wasFindCalled);
Я считаю этот подход немного запутанным, так как вам нужно отслеживать вызов в заглушке, а затем подтверждать его позже в тесте. Я считаю, что примеры NMock и особенно RhinoMocks более выразительны.
Родинки (прокладки): Откровенно говоря, я не люблю родинок, потому что они могут быть использованы не по назначению. Одна из вещей, которые мне так нравятся в модульном тестировании (и в частности TDD), это то, что тестирование вашего кода помогает вам понять, где вы написали плохой код. Это связано с тем, что сложно тестировать плохо написанный код. Это неверно при использовании кротов, потому что кроты на самом деле предназначены для того, чтобы вы могли тестировать зависимости, которые не вводятся, или тестировать частные методы. Они работают так же, как заглушки, за исключением того, что вы используете ShimsContext следующим образом:
using (ShimsContext.Create())
{
System.Fakes.ShimDateTime.NowGet = () => { return new DateTime(fixedYear, 1, 1); };
}
Меня беспокоит то, что люди начнут рассматривать их как «более простой способ модульного тестирования», потому что они не заставляют вас писать код так, как вы должны. Для более полного описания этой концепции см. Этот мой пост:
Для получения дополнительной информации о некоторых проблемах, связанных с фейковыми фреймворками, просмотрите эти сообщения:
Если вы заинтересованы в изучении RhinoMocks, вот обучающее видео Pluralsight (полное раскрытие - я написал этот курс и получаю гонорары за просмотры, но я думаю, что это применимо к этому обсуждению, поэтому я включаю его здесь):
Вы правы, но это еще не все. Наиболее важные вещи, которые следует вынести из этого ответа:
Ваша архитектура должна правильно использовать заглушки и внедрение зависимостей, а не полагаться на костыль фейков и моков.
Подделки и имитации полезны для тестирования кода, который вы не должны или не можете изменять, например:
Прокладки (известные как «Родинки» во время разработки) действительно представляют собой фиктивную структуру, которая работает посредством обходных вызовов. Вместо кропотливого создания имита (да, даже использование Moq относительно болезненно!), Прокладки просто используют уже существующий производственный объект кода. Прокладки просто перенаправляют вызов от производственной цели к делегату тестирования.
Заглушки создаются из интерфейсов в целевом проекте. Объект Stub - это всего лишь реализация интерфейса. Преимущество использования типа «заглушка» заключается в том, что вы можете быстро создать заглушку, не загромождая свой тестовый проект множеством разовых заглушек, не говоря уже о потере времени на их создание. Конечно, вам все равно следует создавать конкретные заглушки для использования во многих тестах.
Эффективная реализация фейков (типов прокладок, макетов и заглушек) требует некоторого привыкания, но стоит затраченных усилий. Я лично сэкономил недели времени на разработку за счет использования типов прокладок / молей, макетов и заглушек. Я надеюсь, вам понравится эта технология, как и мне!
источник
Насколько я понимаю, команда Visual Studio хотела избежать конкуренции с различными имитационными библиотеками, доступными для .NET. MS часто сталкивается с подобными трудными решениями. Их проклинают, если они не обеспечивают определенной функциональности («почему MS не предоставляет нам фиктивную библиотеку; макеты - такое обычное требование?»), И проклинают, если они предоставляют («почему Microsoft так агрессивно действует естественных сторонников ухода с рынка? ») Очень часто, но не всегда, они решают воздержаться от простого предоставления собственной альтернативы доступным и хорошо принятым технологиям. Кажется, здесь так и есть.
Функция прокладки Fakes действительно очень полезна. Конечно, есть опасности. Требуется некоторая дисциплина, чтобы использовать его только там, где это необходимо. Однако он заполняет большой пробел. Моя основная жалоба заключается в том, что он поставляется только с версией Ultimate VS 2012 и поэтому будет доступен только части сообщества разработчиков .NET. Какая жалость.
источник
Подделки включают в себя два разных типа «поддельных» объектов. Первый, называемый «заглушкой», по сути, представляет собой автоматически сгенерированный фиктивный элемент, поведение которого по умолчанию можно (и обычно будет) переопределить, чтобы сделать его более интересным макетом. Однако в нем отсутствуют некоторые функции, которые предлагает большинство доступных в настоящее время фреймворков для фиксации. Например, если вы хотите проверить, что метод в экземпляре заглушки был вызван, вам нужно будет добавить логику для этого самостоятельно. По сути, если вы сейчас создаете свои собственные макеты вручную, заглушки, вероятно, могут показаться улучшением. Однако, если вы уже используете более полнофункциональный фреймворк для фиксации, вам может показаться, что в заглушках Fakes отсутствуют некоторые важные элементы.
Другая категория объектов, предлагаемая Fakes, называемая «прокладкой», предоставляет механизм для замены поведения зависимостей, которые не были (или не могут быть) должным образом отделены для стандартной замены с помощью моков. AFAIK, TypeMock - единственная из основных фреймворков для имитации, которая в настоящее время предлагает такую функциональность.
Кстати, если вы уже пробовали Moles раньше, Fakes - это, по сути, то же самое, наконец-то вышедшее из Microsoft Research в реальный продукт.
источник
Что касается фальшивых (Shim + Stub) объектов, то он был четко определен выше, хотя я думаю, что последний абзац в последнем комментарии довольно хорошо резюмирует всю ситуацию.
Хотя многие люди будут утверждать, что объекты Fake (Shim + Stub) являются хорошими активами в некоторых случаях модульного тестирования, недостатком является то, что независимо от того, используете ли вы Visual Studio 2012 или Visual Studio 2013, эти параметры доступны ТОЛЬКО. с версиями Premium или Ultimate. IOW, это означает, что вы НЕ БУДЕТЕ запускать ЛЮБУЮ из этих подделок (Shim + Stub) на любой версии Pro.
Вероятно, вы можете увидеть опцию меню Fakes (Shim + Stub) в Pro-версиях, но будьте осторожны, есть довольно высокие шансы, что вы в конечном итоге ничего не получите ... Это не вызовет никаких ошибок компиляции, сообщающих вам, что что-то важное отсутствует, вариантов просто нет, так что не теряйте время ...
Это важный фактор, который следует учитывать в команде разработчиков, особенно если одна из них использует версию Ultimate, а все остальные используют версию Pro ... Moq, с другой стороны, можно легко установить через Nuget независимо от того, какую версию Visual Studio вы используете. У меня не было проблем с использованием Moq, ключ к любому инструменту - знать, для чего они используются и как их использовать правильно;)
источник