Я - поблочное тестирование ICustomerRepository
интерфейс используется для получения объектов типа Customer
.
ICustomerRepository
этим способом?4
когда я знаю, что только поместил 5
в репозиторииЯ, вероятно, пропускаю что-то очевидное, но это кажется интеграционными тестами класса, который реализует ICustomerRepository
будет иметь больше ценности.
[TestClass]
public class CustomerTests : TestClassBase
{
private Customer SetUpCustomerForRepository()
{
return new Customer()
{
CustId = 5,
DifId = "55",
CustLookupName = "The Dude",
LoginList = new[]
{
new Login { LoginCustId = 5, LoginName = "tdude" },
new Login { LoginCustId = 5, LoginName = "tdude2" }
}
};
}
[TestMethod]
public void CanGetCustomerById()
{
// arrange
var customer = SetUpCustomerForRepository();
var repository = Stub<ICustomerRepository>();
// act
repository.Stub(rep => rep.GetById(5)).Return(customer);
// assert
Assert.AreEqual(customer, repository.GetById(5));
}
}
Протестируйте базовый класс
public class TestClassBase
{
protected T Stub<T>() where T : class
{
return MockRepository.GenerateStub<T>();
}
}
ICustomerRepository и IRepository
public interface ICustomerRepository : IRepository<Customer>
{
IList<Customer> FindCustomers(string q);
Customer GetCustomerByDifID(string difId);
Customer GetCustomerByLogin(string loginName);
}
public interface IRepository<T>
{
void Save(T entity);
void Save(List<T> entity);
bool Save(T entity, out string message);
void Delete(T entity);
T GetById(int id);
ICollection<T> FindAll();
}
Правило №1 тестирования:
Прежде чем писать тест, узнайте, какова его цель и что он пытается доказать. Если вы не знаете, что он доказывает, то он бесполезен :)
Как правильно сказали другие постеры, вы делаете заглушку интерфейса и затем вызываете заглушку - это ничего не доказывает о том, работает ли ваш производственный код.
Что такое заглушка?
Заглушки используются для предоставления консервированных значений для управления некоторым аспектом тестируемого класса. Например, допустим, у вас есть CustomerService
, который имеет экземпляр типа ICustomerRepository
. Если вы хотите убедиться, что CustomerService
может изящно обработать случай ошибки, когда хранилище пусто, вы бы заглушили метод ICustomerRepository
GetCustomerById
, чтобы вернуть ничего/null/выбросить исключение, а затем убедились, что метод CustomerService
сделал правильную вещь (например, вернул результат customer not found).
Т.е. заглушка - это просто коллаборатор, который помогает достичь интересующего вас конкретного состояния/поведения. Мы тестируем CustomerService
, а заглушка ICustomerRepository
просто помогает нам достичь цели.
Вы не первый, кто задает именно этот вопрос :). Я обычно советую разработчикам сначала вручную накручивать двойники тестов. Это помогает понять все взаимодействия и то, что фреймворк на самом деле делает для вас.
Ваш тест для меня не имеет смысла. Вы проверяете, возвращает ли предварительно запрограммированная заглушка значения, которые вы ей скармливаете. Вы не тестируете какой-либо реальный код.
Следуйте ответу dcp. Интерфейс - это объявление методов. Вы должны протестировать их реализацию.
Возможно, я что-то упускаю, но кажется, что каждый аспект вашего теста смоделирован?
Вообще говоря, вы моделируете только те объекты, которые не являются основными для теста. В данном случае вы можете использовать это хранилище в качестве источника для функции, которая, как вы ожидаете, сделает что-то с хранилищем, чтобы получить клиента #5 и выполнить над ним операцию.
Например, вы можете создать макет хранилища клиентов, чтобы вызвать метод, который проверяет логин пользователя. Вы будете использовать свой макет хранилища для того, чтобы ваш юнит-тест не полагался на реальный источник данных, а не для тестирования своего макета хранилища.
Интерфейсы, по определению, это просто контракты, поэтому нет кода для тестирования. Вы хотите писать модульные тесты против конкретной реализации (реализаций) интерфейса, потому что именно там находится реальный код выполнения.
Если конкретной реализации интерфейса нет, и вы просто передразниваете конкретную реализацию, то ваш модульный тест основан только на передразнивании. Это не имеет особой ценности.