Разрешение для тестирования Presenter Model Viewer ... Использую ли я объекты DTO или Domain или оба? - PullRequest
0 голосов
/ 07 декабря 2011

Основная проблема в том, как протестировать докладчика.

Примите: Доменный объект (в конечном итоге будет сохранен в БД) Базовые атрибуты: Id (идентификатор БД, Int / GUID / любой другой) и TransientID (локальный идентификатор до сохранения, GUID)

DomainObject

<Code>
namespace domain {  
  public class DomainObject {    
   private int _id;    
   private Guid transientId;    
   public DomainObject()
   {      
    _transient_Id = Guid.NewGuid();    
   }
  }
}
</Code>

PresenterTest:


var repository = Mock.StrictMock();
var view = Mock.StrictMock();

view.Save += null;
var saveEvent = LastCall.Ignore().GetEventRaiser();

var domainObject = new DomainObject() {Id = 0, Attribute = "Blah"};

Mock.ExpectCall(Repository.Save(domainObject)).Returns(True);
Mock.ReplayAll();

var sut = new Presenter(repository, view);
Save_Event.raise(view, EventArgs.Empty);

Mock.Verify()

Таким образом, проблема в том, что идентификатор объекта домена вычисляется с помощью ID, а если он не рассчитывается с помощью transientID, нет никакого способа узнать, каким будет transientID, поэтому я не могу проверить фиктивный репозиторий на равенство.

Обходные пути на данный момент:

1) LastCall. Игнорируйте и довольствуйтесь jsut-проверкой, что метод вызван, но не проверяйте содержимое вызова.

2) Напишите DTO для проверки и сохранения в сервисе. Служба, которая обрабатывает сопоставление с доменом.

3) Напишите фальшивый testRepository, который использует собственную логику для определения успеха.

- 1 не проверяет большую часть логики. --2 - много лишнего кода без какой-либо цели --3 Кажется потенциально хрупким.

Прямо сейчас я склоняюсь к DTO и сервису в теории, что это дает наибольшую изоляцию между уровнями, но, вероятно, 75% ненужно ...

Ответы [ 2 ]

1 голос
/ 07 декабря 2011

нет способа узнать, каким будет transientID, поэтому я не могу проверить фиктивный репозиторий на равенство.

На самом деле, я думаю, что здесь есть возможность.

Вместо вызова Guid.NewGuid() вы можете создать свой собственный класс GuidFactory, который генерирует GUID.По умолчанию он будет использовать Guid.NewGuid() внутри, но вы можете взять его под контроль для тестов.

public static class GuidFactory
{
    static Func<Guid> _strategy = () => Guid.NewGuid();

    public static Guid Build()
    {
        return _strategy();
    }

    public static void SetStrategy(Func<Guid> strategy)
    {
        _strategy = strategy;
    }
}

В вашем конструкторе вы замените Guid.NewGuid() на GuidFactory.Build().

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

Например:

public class PseudoTest
{
    IList<Guid> GeneratedGuids = new List<Guid>();

    public void SetUpTest()
    {
        GuidFactory.SetStrategy(() => 
        {
            var result = Guid.NewGuid();
            GeneratedGuids.Add(result);
            return result;
        });
    }

    public void Test()
    {
        systemUnderTest.DoSomething();
        Assert.AreEqual(GeneratedGuids.Last(), someOtherGuid);
    }
}
1 голос
/ 07 декабря 2011

WPF помог мне понять, что вам действительно не нужно много тестировать, если таковые имеются, на Controller / Presenter / VM.Вы действительно должны сосредоточить все свои тесты на моделях и сервисах, которые вы используете.Должна быть вся бизнес-логика, модель представления, презентатор или контроллер должны быть максимально легкими, и единственная роль заключается в передаче между моделью и представлением туда и обратно.

Какой смысл проверять, вызываете ли вы сервис, когда команда кнопки делает это для докладчика?Или тестирование, правильно ли подключено событие?

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

Тощие контроллеры / ВМ / Презентаторы.Толстые модели.

Это мой ответ, потому что я столкнулся с той же проблемой, пытаясь протестировать модели представления, я потратил столько времени, пытаясь выяснить, как лучше их тестировать, и другой разработчик выступил с отличным докладом о Model-View.шаблоны с этим аргументом.Не тратьте слишком много времени на их тестирование, сосредоточьтесь на моделях / услугах.

...