Я часто вижу эту проблему - вы в корне не понимаете, в чем заключается цель насмешек / фальсификаций / окурков.То есть вы пишете тест для поддельной реализации, и в результате тест бесполезен .Подумайте об этом - что ваш тест пытается доказать?Вы пытаетесь проверить, что можете получить результаты из репозитория, но:
// this is a mock/fake/stub/whatever, it's NOT the real class
var repository = new Mock<IAdministrateurRepository>();
// and so.. what is the point in this when your
// IAministratorRepository is not the production version?
var administrateur = repository.SelectById(monGuid);
// The repository is meant to be the focus of the test,
// yet you're not testing a result of using a real class
administrateur.ShouldNotBeNull();
administrateur.Id.ShouldEqual(monGuid);
Приведенная выше строка извлекает данные из вашего репозитория, но репозиторий не является реальной реализацией.Это не производственный код.Если так, то почему вы тогда утверждаете на объекте Administrator
, который извлекается из поддельного хранилища?Поведение, которое вы тестируете, - это функция поиска по идентификатору, но она определяется внутри вашего тестового устройства!Вы создали заглушенную / фальшивую реализацию, а затем протестировали ее - больше ничего.Предполагается, что Mocks / Stubs / Fakes должны иметь ожидания или предоставлять постоянные результаты для тестирования реальных типов (читай: типы, используемые в производстве).Тестирование самого макета ничего не дает.
Прежде чем писать какой-либо тестовый код, вы должны спросить себя Какова цель этого теста? Если вы не можете ответить на этот вопрос, разрешите его раньшеВы пишете тестовый код.Если бы вы на самом деле тестировали ваш AdministratorRepository
, вы бы создали экземпляр рабочей версии кода репозитория, а затем манипулировали им, а затем утверждали какой-то аспект его поведения.
Это сообщение в блоге может помочь вам.Я бы выступил за отказ от использования основ mocking и использования тестирования на основе состояния, пока вы не будете полностью уверены в том, куда вписывается mocking / stubbing, так как тестирование на основе взаимодействия легко запутать.
* edit - Хорошо, вот (примерно) как должен выглядеть ваш код Игнорируйте детали реализации, просто сосредоточьтесь на ролях каждого типа и обратите внимание, что это просто, как может быть.
// interface
public interface IAdministratorRepository
{
Administrator SelectById(Guid _id);
void Add(Administrator _admin);
}
// minimal implementation of admin.
public class Administrator
{
public Guid Id { get; set; }
public Administrator(Guid _id)
{
Id = _id;
}
}
/// <summary>
/// For argument's sakes, this is the class under test.
/// It's not a mock/fake/stub/whatever; it's the real deal!
/// </summary>
public class RealAdministratorRepository : IAdministratorRepository
{
private Dictionary<Guid, Administrator> m_items = new Dictionary<Guid, Administrator>();
public Administrator SelectById(Guid _id)
{
// no error handling here; keeping it simple
if(m_items.ContainsKey(_id))
return m_items[_id];
return null;
}
public void Add(Administrator _admin)
{
// No error handling for brevity's sakes
m_items.Add(_admin.Id, _admin);
}
}
// now, here's a very, very simple happy path test for SelectById using
// the real implementation of AdministratorRepository
[TestFixture]
public class AdministratorRepositoryTests
{
private const string AdminId = "a05fd3de-9ae4-4b0b-b560-fd96678d3019";
private IAdministratorRepository m_repository;
[SetUp]
public void PerTestSetUp()
{
// no mocks/stubs required. m_repository is a RealAdministratorRepository
// because that's our production class and that's what we want to test!
m_repository = new RealAdministratorRepository();
m_repository.Add(new Administrator(new Guid(AdminId)));
}
[Test]
public void SelectById_WithItemsInRepository_ReturnsCorrectItems()
{
// ignore the fact that I'm repeating the same string 3 times; brevity again
var item = m_repository.SelectById(new Guid(AdminId));
Assert.That(item, Is.Not.Null);
Assert.That(item.Id, Is.EqualTo(new Guid(AdminId)));
}
}
Обратите внимание, что яне использую насмешливые рамки, потому что мне это не нужно.Производственный код не имеет проблемных зависимостей, которые требуют насмешек / заглушек / подделок.