2015-06-29 2 views
3

Я пишу модульные тесты для своего уровня обслуживания, и я полностью вижу смысл создания модульных тестов для проверки логики. Например, если я создаю функцию, которая добавляет два числа, обязательно напишите для этого единичный тест.Какие-либо методы тестирования единиц измерения, которые используют EF или Linq?

Но если в моем методе обслуживания слоя у меня есть что-то вроде этого

public ICollection<MyEntity> GetAll() 
{ 
    return _context.MyEntities 
     .Where(e => !e.IsDeleted) 
     .ToList(); 
} 

Что такое точка в блоке тестирования это? Поскольку я получаю это из базы данных, кажется глупому издеваться над базой данных, потому что я просто предполагаю, что Linq работает так, как должно быть?

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

Я знаю, что тестирование против базы данных делает это более интеграционным тестом, но действительно ли это подходит для модульного тестирования?

Что делать, если я еще один пример, скажем, это

public int Delete(long id) 
{ 
    _context.Database.ExecuteCommand("DELETE FROM myTable WHERE Id = ?", id); 

    return _context.SaveChanges(); 
} 

Как эта функция может быть протестированы? Если я mock _context.Database и создаю единичный тест, который проверяет, вызывает ли _context.SaveChanges (что я не вижу смысла в том, что так когда-либо), нет никаких гарантий, что он фактически удалит мои данные. Что, если у меня есть ограничение внешнего ключа? Макет прошел бы, но реальный метод действительно потерпел бы неудачу?

Я только начинаю думать, что, если метод фактически не вычисляет какую-то логику, я не вижу смысла/причины для создания модульного теста, особенно при использовании инфраструктуры Entity?

+4

Вы должны выполнить его проверку, чтобы убедиться, что ваш код Linq верен. Что, если бы вы набрали '.Where (e => e.IsDeleted) .ToList();' по ошибке, или кто-то случайно отредактировал его или иначе сломал его позже? –

+2

Используйте макет для модульного тестирования. Использование реальной базы данных - это интеграционное тестирование. –

+1

IMO в таких сценариях, где тестовый код скоро окажется более сложным, чем производственный код - хороший средний уровень - это тесты поведения («после того, как я добавил что-то в свою базу данных, я могу найти его снова ...») - но это только [мое мнение] (https://www.youtube.com/watch?v=XVCtkzIXYzQ) (и я думаю, что это проблема с этим потоком - извините) – Carsten

ответ

0

Для кода, связанного с базой данных, я бы фактически протестировал реальную базу данных, а не макет. Это единственный способ убедиться, что SQL действителен (вы пишете его вручную или позволяете ORM генерировать его для вас). Есть инструменты, чтобы сделать это проще, например Respawn.

+1

@Downvoter: поделитесь своими мыслями о том, почему этот ответ неверен? –

0

Я думаю, что это имеет смысл для модульного тестирования практически все типов функций:

«Какой смысл в блоке тестирует Так как я получаю это из базы данных, кажется, глупо высмеивать базу данных, так как Тогда я просто предполагаю, что Linq работает так, как должно быть?

  • Вы не тестируете Linq, но вы тестируете функцию; функция имеет имя GetAllAsync; и я просто могу предположить, что это вернет все экземпляры MyEntity, хранящиеся в базе данных. Но он просто возвращает только удаленные элементы; модульное тестирование - это не просто проверка правильности работы функции; это также способ проверить правильность присвоения этой функции.
  • Также у этой функции есть проблема; что если

    _context.MyEntities (e =>! e.IsDeleted) возвращает null? ToList выдает исключение. Тогда модульное тестирование поможет выявить потенциальные проблемы, если вы проверите экстремальные значения.

  • Кроме того, модульное тестирование заставляет вас использовать абстракцию. Если вы не можете тестировать метод методом, у метода могут быть проблемы, вам необходимо изучить этот метод и повторить фактор.

    _context.Database.ExecuteCommand ("УДАЛИТЬ ОТ myTable WHERE Id =?", id). По моему мнению, эта строка кода должна оставаться где-то в другом месте, а не на уровне обслуживания (в репозитории, возможно?) .Что, если id равен« -1 »? Как вы будете обрабатывать исключение?

Я думаю, что это очень трудно сформулировать общие правила о методах не модульное тестирования, которые включают Linq.

+0

Да, жаль насчет наименования, но просто написал быстрый пример. Пункт 2, см. Свою точку зрения на это. Точка 3, у меня нет репозитория. Поскольку EF использует шаблон репозитория/UOW, я не видел смысла создания другого слоя абстракции ради него, это кажется бессмысленным. Поскольку это мой первый проект, в котором я пишу модульные тесты, довольно сложно выяснить, что тестировать, что не тестировать и как тестировать. Похоже, я могу написать больше тестов, чем реальный код ?! – Gillardo

+0

Это не другой слой абстракции «ради него», если он облегчает тестируемость. – BenjaminPaul

+0

Но если я создам слой репозитория, мой сервисный уровень вызовет это. Хорошо, теперь я могу издеваться над тем, что при тестировании уровня сервиса, но как насчет тестирования нового уровня репозитория? Вы издеваетесь над этим или проверяете уровень репозитория против реальной базы данных? – Gillardo

0

Почему вы модульное тестирование функцию, которая складывает два числа? вы не тестируете оператор + больше, чем вы пытаетесь протестировать LINQ или EF. Вы проверяете поведение, поэтому оно совершенно верно для проверки того, что вы можете считать «просто работающим». Если, например, я запретил использование EF в вашем приложении, вам все равно понадобится тест для обеспечения правильности того, что вы с функцией.

Где вы хотите нарисовать линию?

+0

добавить два числа было простым примером, но моя точка зрения, где вам нарисовать линию? Как я сказал в другом посте, вы могли бы написать больше модульных тестов, чем фактический код? Если я нахожу ошибку в своем приложении, я пишу для нее тест, он терпит неудачу. Я исправлю это, тест проходит. Достаточно справедливо, но как вы можете писать тесты заранее для всех возможных исключений? Где вы остановились? – Gillardo

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