Я объясню, что я делаю, почему и сколько я получу от этого.
Во-первых, я делаю точно , что вы делаете, относительно ваших репозиториев. Несмотря на некоторые различия в именах, я тоже так делаю:
- MyProject.Repositories.IUserRepository
- MyProject.Repositories.Fake.UserRepository
- MyProject.Repositories.SqlServer.UserRepository
С моим поддельным UserRepository я также просто создаю и заполняю коллекцию private IEnumerable<User>
(которая является List<User>
). Почему у меня это? Я использую этот репозиторий для моей начальной ежедневной разработки (потому что это быстро -> нет доступа к БД == быстро!). Затем я переключаюсь на поддельные респираторы для репозиториев sql (т. Е. Изменяю мою инъекцию зависимостей (ооооооооо!)). Вот почему этот класс / пространство имен существует, в отличие от использования Mocks в моем модульном тесте для «поддельных» вещей. (Такое бывает, но при других обстоятельствах).
Я использую LinqToSql для моего sql-сервера UserRepository. Что касается вашего вопроса, то неважно, что я использую LinqToSql ... это может быть любая другая оболочка базы данных. Здесь важно то, что есть стороннее что-то , в которое я интегрирую с.
Хорошо, отсюда мне нужно убедиться в двух вещах
- Ложный пользовательский репозиторий работает
- Работает sql-сервер UserRepository.
Прежде всего, большинство людей не создают модульный тест для фальшивых вещей. Это поддельный кусок какашки, так зачем тратить энергию? Правда --- за исключением того, что я использую этот фальшивый кусок какашки в своем повседневном развитии (см. Мой комментарий об этом выше). Так что я быстро соберу несколько базовых юнит-тестов. ПРИМЕЧАНИЕ: В мои глаза это модульные тесты, хотя они repository
классов. Зачем? Они не интегрируют с третьей стороной / инфраструктурой.
Далее (наконец-то я дошел до сути) я делаю отдельный тестовый класс, который является интеграционным тестом. Это модульный тест, который интегрируется с чем-то вне системы. Это может быть настоящий API Twitter. Это может быть настоящий API S3 Amazon. Обратите внимание, что я использовал слово real . Это ключ, здесь. Я интегрируюсь с реальным сервисом вне моего. Как таковой -> это медленно. Каждый раз, когда мне нужно оставить свой компьютер для каких-то данных, это называется , объединяющим , и вы автоматически предполагаете (и ожидаете), что это будет медленно.
Итак, я интегрируюсь с базой данных.
(Nae sayers, пожалуйста, не говорите об этом с дерзкими предположениями, что у вас есть база данных на том же компьютере ... вы покидаете свой ПРИЛОЖЕНИЕ "мир").
Ничего себе. это какой-то роман "Война-и-мир" ... время для каких-то жестких действий, хулиганский код.
Давай принесем!
namespace MyProject.Tests.Repositories.SqlServer
{
// ReSharper disable InconsistentNaming
[TestClass]
public class UserRepositoryTests : TestBase
{
[ClassInitialize]
public static void ClassInitialize(TestContext testContext)
{
// Arrange.
// NOTE: this method is inherited from the TestBase abstract class.
// Eg. protected IUserRepository =
// new MyProject.Respositories.SqlServer
// .UserRespository(connectionString);
InitializeSqlServerTestData();
}
[TestMethod]
public void GetFirst20UsersSuccess()
{
// Act.
var users = _users.GetUsers()
.Take(20)
.ToList();
// Assert.
Assert.IsNotNull(users);
Assert.IsTrue(users.Count() > 0);
}
}
}
Хорошо, давайте пробежимся по этому щенку.
Прежде всего, это использует модульное тестирование Microsoft - встроенное в бета-версию VS2010 или версию Team2008 VS2008 (или что бы это ни было ... я просто устанавливаю копию, купленную нашей работой).
Во-вторых, всякий раз, когда класс инициализируется впервые (будь то один тест или несколько), он создает context
. В моем случае это мой репозиторий Sql Server, который будет использовать контекст LinqToSql. (Ваш будет контекстом EF). Это Arrange часть TDD.
В-третьих, я называю метод -> это часть Act TDD.
Наконец, я проверяю, вернул ли я то, что ожидал -> это часть Assert TDD.
А как насчет обновления БД?
Просто следуйте той же схеме, за исключением того, что вы, возможно, захотите обернуть свой код вызова в транзакцию и откатить ее обратно. В противном случае вы можете получить сотни строк данных, которые могут быть одинаковыми. Недостаток этого? Любые поля identity
не будут иметь всю красивую и красивую последовательность нумерации (потому что откат будет «использовать» это число). Не имеет смысла? не волнуйся это продвинутый совет, который я решил добавить, чтобы проверить вас, но это означает приседание для этого адского длинного поста.
так .. ээ ... да. это то, чем я занимаюсь. Не знаю, будут ли боги программирования на этих форумах переворачиваться и поливать грязью мой путь, но мне это нравится, и я надеюсь, что это поможет вам.
НТН.