模拟Enterprise Lib 5'数据库'

hol*_*see 6 .net c# unit-testing enterprise-library

是否可以模拟企业库5版的"数据库"?如果是这样......怎么样?

没有IDatabase接口(这是一个谜,因为我虽然微软P&P会更多关于暴露这种接口的可测试性优势).

我有一个使用EntLib 5数据访问应用程序块的Repository类.

我将单元测试改编成这个类,需要模拟出对Database对象的依赖.此类现在通过其构造函数传递给数据库,并使用Database对象在Db上执行操作.

我使用以下内容来解析要传递给我的存储库的数据库实例:

Container.RegisterType<IFooRepository, FooRepository>(
    new InjectionConstructor(
        EnterpriseLibraryContainer.Current.GetInstance<Database>("FooDbConnStr")
    )
);
Run Code Online (Sandbox Code Playgroud)

我不希望这些单元测试成为集成测试.

我已经尝试使用Moq来创建数据库类型的动态模拟,但事实证明这很棘手,因为数据库需要在其构造函数中使用连接字符串和DbProviderFactory.也许如果有像MockDbProviderFactory这样的东西.

这是单元测试采用的形式:

EntLib UnitTest尝试模拟数据库

旁白:我还发现使用静态记录器类很难测试.希望我在这里缺少一些技巧,但我必须说到目前为止我对可测试性感到失望.

hol*_*see 2

我使用 FakeItEasy http://code.google.com/p/fakeiteasy/

我创建了一个 SqlDatabase 的模拟(继承自 Database,具有更友好的构造函数),将其传递给 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);
}
Run Code Online (Sandbox Code Playgroud)