Mocking Enterprise Lib 5 'База данных' - PullRequest
6 голосов
/ 18 августа 2010

Можно ли издеваться над версией базы данных для корпоративной библиотеки 5? Если так ... как?

Нет интерфейса IDatabase (что является загадкой, так как я думаю, что Microsoft P & P будет более заинтересована в преимуществах тестируемости такого интерфейса).

У меня есть класс репозитория, который использовал блок приложения доступа к данным EntLib 5.

Я тестирую юнит-тесты в этом классе, и мне нужно смоделировать зависимость от объекта Database. Этот класс теперь передал базу данных через ее конструктор и использует объект базы данных для выполнения операций с БД.

Я использую следующее для разрешения экземпляра базы данных, который будет передан в мой репозиторий:

Container.RegisterType<IFooRepository, FooRepository>(
    new InjectionConstructor(
        EnterpriseLibraryContainer.Current.GetInstance<Database>("FooDbConnStr")
    )
);

Я не хочу, чтобы эти модульные тесты стали интеграционными.

Я пытался использовать Moq для создания динамического макета типа Database, но это оказалось непростым делом, так как Database требует строки подключения и DbProviderFactory в своем конструкторе. Возможно, если бы существовала такая вещь, как MockDbProviderFactory .

Это форма, которую принимает модульный тест:

EntLib UnitTest Attempt to Mock Database

Кроме того: я также считаю, что использование класса статического регистратора очень сложно проверить. Надеюсь, мне здесь не хватает какой-то хитрости, но я должен сказать, что пока разочарован тестируемостью.

Ответы [ 4 ]

3 голосов
/ 27 марта 2013

FWIW, я смог смоделировать SqlDatabase, используя Moq. SqlDatabase имеет атрибут SqlClientPermission, который не очень хорошо работает с Castle Windsor (используется Moq). Мне пришлось явно указать Каслу игнорировать атрибут SqlClientPermission, чтобы заставить тест работать (см. Строку 1 в примере ниже). Ниже приведен пример единичного теста (пример заимствования Стивена Х).

    [TestMethod]
    public void FooRepo_CallsCorrectSPOnDatabase()
    {
        Castle.DynamicProxy.Generators.AttributesToAvoidReplicating.Add(typeof(System.Data.SqlClient.SqlClientPermissionAttribute));
        var mockSqlDb = new Mock<SqlDatabase>("fake connection string");
        mockSqlDb.Setup(s => s.GetStoredProcCommand("sp_GetFoosById"));
        var sut = new FooRepository(mockSqlDb);
        sut.LoadFoosById(1);
        mockSqlDb.Verify(s => s.GetStoredProcCommand("sp_GetFoosById"), Times.Once(), "Stored Procedure sp_GetFoosById was not invoked.");
    }
2 голосов
/ 18 августа 2010

Я использовал FakeItEasy http://code.google.com/p/fakeiteasy/.

Я создал макет SqlDatabase (наследует от базы данных с дружественным конструктором), передал его в FooRepostory, вызвал тестируемую функцию и подтвердил ожидаемые вызовы, которые были сделаныБаза данных.

[Test]
public void FooRepo_CallsCorrectSPOnDatabase()
{
    var mockDb = A.Fake<SqlDatabase>(x => x.WithArgumentsForConstructor(new object[] { "fakeconnStr" }));
    var sut = new FooRepository(mockDb);
    sut.LoadFoosById(1);
    A.CallTo(() => mockDb.GetStoredProcCommand(Db.SProcs.GetFoosById)).MustHaveHappened(Repeated.Once);
}
1 голос
/ 11 декабря 2010

Я лично загрузил исходный код и использовал ReSharper для извлечения интерфейса для объекта базы данных. Он восстановлен, и я использовал мои собственные двоичные файлы. Wala - интерфейс! Подсказка: интерфейсы просто издеваются. Почему Microsoft P & P group этого не сделала, я не знаю.

1 голос
/ 21 августа 2010

База данных является абстрактным базовым классом, и DbProviderFactory также является абстрактным, так что вы можете смоделировать их обоих. Пока вы макетируете операции, которые вы вызываете для типа базы данных (почти все, что там виртуально, так что у вас должно быть все в порядке), вам на самом деле ничего не нужно делать на фабрике провайдеров. И строка подключения может быть просто пустой или нулевой или как угодно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...