Я решил начать писать модульные тесты в нашем приложении.Он использует Entity Framework с шаблоном хранилища.
Теперь я хочу начать тестирование логических классов, которые используют хранилища.Здесь я приведу простой пример.
Три моих метода в классе GenericRepository:
public class GenericRepository : IRepository
{
public IQueryable<TEntity> GetQuery<TEntity>() where TEntity : class
{
var entityName = GetEntityName<TEntity>();
return Context.CreateQuery<TEntity>(entityName);
}
private string GetEntityName<TEntity>() where TEntity : class
{
return typeof(TEntity).Name;
}
public IEnumerable<TEntity> Find<TEntity>(Expression<Func<TEntity, bool>> predicate) where TEntity : class
{
return GetQuery<TEntity>().Where(predicate).AsEnumerable();
}
}
Простой логический класс, возвращающий отдельные годы из календарной таблицы в порядке убывания (да, я знаю,в нашем коде слово слово написано с ошибкой):
public class GetDistinctYearsFromCalendar
{
private readonly IRepository _repository;
public GetDistinctYearsFromCalendar()
{
_repository = new GenericRepository();
}
internal GetDistinctYearsFromCalendar(IRepository repository)
{
_repository = repository;
}
public int[] Get()
{
return _repository.Find<Calender_Tbl>(c => c.Year.HasValue).Select(c => c.Year.Value).Distinct().OrderBy(c => c).Reverse().ToArray();
}
}
И вот мой первый тест:
[TestFixture]
public class GetDistinctYearsFromCalendarTest
{
[Test]
public void ReturnsDistinctDatesInCorrectOrder()
{
var repositoryMock = new Mock<IRepository>();
repositoryMock.Setup(r => r.Find<Calender_Tbl>(c => c.Year.HasValue)).Returns(new List<Calender_Tbl>
{
new Calender_Tbl
{
Date =
new DateTime(2010, 1, 1),
Year = 2010
},
new Calender_Tbl
{
Date =
new DateTime(2010, 2, 1),
Year = 2010
},
new Calender_Tbl
{
Date =
new DateTime(2011, 1, 1),
Year = 2011
}
}.AsQueryable());
var getDistinct = new GetDistinctYearsFromCalendar(repositoryMock.Object).Get();
Assert.AreEqual(2, getDistinct.Count(), "Returns more years than distinct.");
Assert.AreEqual(2011, getDistinct[0], "Incorrect order, latest years not first.");
Assert.AreEqual(2010, getDistinct[1], "Wrong year.");
}
}
Это работает нормально.Но на самом деле это не то, что я хочу сделать.Поскольку мне нужно настроить метод Find для фиктивного объекта, мне также нужно знать, как он будет вызываться в моем логическом классе.Если я хотел бы сделать TDD, я не хочу возражать по этому поводу.Все, что я хочу знать, это то, какие объекты Календаря должен предоставлять мой репозиторий.Я хотел бы настроить метод GetQuery.Например:
repositoryMock.Setup(r => r.GetQuery<Calender_Tbl>()).Returns(new List<Calender_Tbl>
{
new Calender_Tbl
{
Date =
new DateTime(2010, 1, 1),
Year = 2010
},
new Calender_Tbl
{
Date =
new DateTime(2010, 2, 1),
Year = 2010
},
new Calender_Tbl
{
Date =
new DateTime(2011, 1, 1),
Year = 2011
}
}.AsQueryable());
Поэтому, когда Find вызывает внутренний метод GetQuery в классе GenericRepository, он должен получить правильные объекты Calendar, которые я настроил в GetQuery.Но это не работает, конечно.Поскольку я не настроил метод Find моего фиктивного объекта, я не получаю никаких сущностей.
Так что же делать?Конечно, я мог бы использовать Moles или какой-то другой фреймворк, который все издевается, но я не хочу этого делать.Могу ли я что-нибудь сделать в дизайне класса или теста, чтобы решить проблему?
Это не конец света, если я должен идти с моим текущим решением, но что, если год собственности превращается вне обнуляемый int?Тогда, конечно, мне придется изменить свою реализацию в классе логики, но мне также придется изменить тест.Я хотел бы попытаться избежать этого.