Я ищу способы сделать следующее более краткое.
public class MyTests
{
IPresenter presenter;
[SetUp]
public void SetUp()
{
presenter = MockRepository.GenerateStub<IPresenter>();
}
...
}
В особенности определение типа снова при создании насмешки кажется избыточным. Например, я могу записать этому этот путь и использовать отражение, чтобы получить тип и создать тупик автоматически:
public class MyTests
{
IPresenter presenter;
[SetUp]
public void SetUp()
{
Stub(x => x.presenter);
}
void Stub(Expression<Func<MyTests, object>> expression)
{
...
}
}
Это работало бы, но компилятор больше не может обнаруживать того предъявителя, присвоен и начинает выдавать предупреждения. Это также делает ReSharper очень недовольным.
Кто-либо может предложить лучший подход?
Это может быть спорным, но я предпочитаю читабельность, а не DRY-ness* в единичных тестах.
Другими словами, установленные методы не существуют в моих модульных тестах. Они используются только для интеграционных тестов. Я считаю, что XUnit.NET тоже придерживается этой позиции.
Поэтому, чтобы ответить на ваш вопрос, я бы действительно не стал беспокоиться о том, чтобы в каждом из ваших тестов настраивать имитационные презентации, для которых они нужны. Некоторые тесты могут не нуждаться в инсценировке ведущего, поэтому наличие одного ведущего перед запуском теста не является обязательным.
**Естественно, мои юнит-тесты проходят в среднем десять строк, если это увеличивается или объем настройки теста (после AAA - Arrange, Act Assert) велик, только тогда я удалю дублирование и создам вспомогательные методы. Чтобы прояснить этот момент, для более чистых тестов можно создать базовый класс теста, который содержит вспомогательные методы и другой набор настроек code.*
.Это общая боль с C #, что она не выводится в типе из результата метода (в отличие от Java), и оно болезненно во многих ситуациях (просто чтобы дать другой пример, где вы хотите реализовать метод десериала) Отказ Лично я не люблю использовать ключевое слово VAR, потому что я хочу видеть именно то, что такое тип моих объектов, я бы предпочел пропустить имя типа в шаблоне.
В любом случае, если мои тесты приятные, а маленькие, я склонен инициатировать все издевательства в каждом тестовом случае. Таким образом, вы можете посмотреть на все тесты в разделении от других испытаний и сразу увидеть, что там происходит. Если они договариваются, хотя я просто использую противный способ, которым вы встали в начале вашего вопроса.
Да, вообще не использовать [Setup]
и переменные-члены, вместо этого записать Fixture Objects с помощью методов создания.
Объект фиксации будет просто держать в руках соответствующий макет и другие части фиксации.
Я лично использую AutoFixture как Объект Исправлений, и настроил его как Auto-Mocking Container для загрузки, так что мне не нужно писать код имитации, если только мне не нужно явно определить некоторое поведение.
Вот недавний пример юнит-теста:
[TestMethod]
public void DeleteProductWillDeleteProductFromRepository()
{
// Fixture setup
var fixture = new ServiceFixture();
var id = fixture.CreateAnonymous<int>();
var repMock = fixture.FreezeMoq<ProductRepository>();
var sut = fixture.CreateAnonymous<ProductManagementService>();
// Exercise system
sut.DeleteProduct(id);
// Verify outcome
repMock.Verify(r => r.DeleteProduct(id));
// Teardown
}
В данном случае repMock
создан Moq, но я мог бы настроить его на использование Rhino Mocks вместо него.