2009-07-17 3 views
2

Начало работы с TDD и шаблон репозитория, мне интересно, если это имеет смысл тестирования это ...Есть ли смысл испытывать это? (Repository паттерн)

Используя шаблон репозитория, у меня есть этот интерфейс:

public interface ICustomerRepository 
{ 
    IList<Customer> List(); 
    Customer Get(int id); 
} 

У меня есть 50 различных объектов, поэтому 50 различных интерфейсов/реализаций репозитория.

Мой вопрос, если это правильно, чтобы проверить каждое хранилище, насмехаясь над вверх интерфейсом, как:

[TestMethod] 
public void List_Should_Return_Two_Customers() 
{ 
    // Arrange 
    var customerr = new List<Customer>(); 
    customer.Add(new Customer()); 
    customer.Add(new Customer()); 

    var repository = new Mock<ICustomerRepository>(); 
    repository.Setup(r => r.List()).Returns(customer); 

    // Assert 
    Assert.AreEqual(2, repository.Object.List().Count); 
} 

[TestMethod] 
public void Get_Should_Return_One_Customer() 
{ 
    // Arrange 
    var customer = new List<Customer>(); 
    customerr.Add(new Customer() { Id = 1 }); 
    customerr.Add(new Customer() { Id = 2 }); 

    var repository = new Mock<ICustomerRepository>(); 
    repository.Setup(r => r.Get(1)).Returns(customer.Where(w => w.Id == 1).First()); 

    // Assert 
    Assert.IsTrue(repository.Object.Get(1).Id == 1); 
} 

Имеет ли смысл тестирования поддельных реализаций этих интерфейсов? Для меня это не так.

+0

для меня это не имеет смысла, что вы должны использовать слово GOT вместо ИМЕЙТЕ –

+0

С 50 лиц, конечно, вы должны быть в состоянии уменьшить количество хранилищ. У меня есть домен 65 объектов, но у меня есть только 7 репозиториев для них ... Я моделирую репозитории после «хабов» домена или основных понятий, а не для каждого объекта. – womp

+0

На самом деле это был всего лишь номер. Я хочу сказать, что мне нужно будет повторить эти тесты для каждого репозитория. Я не выполняю все классы репозитория. Может быть, в итоге мне будет 20. Я еще не знаю. Мне просто интересно, были ли тесты «правильными»? –

ответ

3

Нет, это не имеет смысла. Очевидно, вы должны тестировать только реализации, а не интерфейсы. В интерфейсе нечего тестировать.

Единственные вещи, проверенные в ваших примерах, - это насмешливая структура, список .NET и некоторые методы расширения LINQ. Нет необходимости проверять их, кто-то еще позаботится об этом.

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

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

0

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

+0

Итак, два теста, которые я написал, на самом деле правильные?Было бы хорошей идеей создавать поддельные классы репозитория, такие как FakeCustomerRepository, с фактическими данными клиента в нем? А затем использовать эту реализацию в моих тестах? –

+1

Да, но вы не должны проверять насмешек. (Это то, что Томми спрашивает, должен ли я проверять насмешек, ответ на меня - нет). Я бы действительно испытал реальные реализации, но не поддельные. –

+1

В других тестах, где вам нужен репозиторий, вы могли/должны использовать фальшивую реализацию, поскольку эти тесты проверяют что-то еще, а не на реализацию «реального» репозитория –

0

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

С уважением.

0

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

public interface IRepository<TEntity> where TEntity : class 
{ 
    IList<TEntity> List(); 
    TEntity Get(int id); 
} 

public abstract class BaseRepository<TEntity> : IRepository<TEntity> where TEntity : class 
{ 
    IList<TEntity> List() 
    { 
     //DataContext.GetTable<TEntity>().ToList(); 
    } 

    TEntity Get(int id) 
    { 
     //Might have to do some magic here... you can use reflection or create 
     //an abstract method that the derived class must override that returns 
     //a delegate id selector. 
    } 
} 
+0

У меня были некоторые проблемы с созданием моих репозиториев. Это сработало, но в конце было не так элегантно, как мне бы хотелось. Bu для метода Get (id) решение, рекомендуем «где TEntity: IdEntity» или аналогичный, при этом IdEntity является реальным классом, который имеет свойство Id и другую информацию о сохранении. – LegendLength

Смежные вопросы