代码之家  ›  专栏  ›  技术社区  ›  holsee

模拟企业Lib 5“数据库”

  •  6
  • holsee  · 技术社区  · 14 年前

    是否可以模拟“数据库”的EnterpriseLibrary5版本?如果是的话。。。怎样?

    没有IDatabase接口(这是一个谜,因为我认为微软P&P会更关注公开这种接口的可测试性好处)。

    我有一个使用entlib5数据访问应用程序块的存储库类。

    我正在将单元测试重新装配到这个类中,需要模拟对数据库对象的依赖关系。这个班是 现在 通过其构造函数传递数据库,并使用数据库对象对数据库执行操作。

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

    我不希望这些单元测试变成集成测试。

    我曾尝试使用Moq来创建数据库类型的动态模拟,但事实证明这很棘手,因为数据库在其构造函数中需要连接字符串和DbProviderFactory。如果有一件事

    这是单元测试的形式:

    EntLib UnitTest Attempt to Mock Database

    4 回复  |  直到 14 年前
        1
  •  3
  •   Ganga    11 年前

    FWIW,我可以用Moq模拟SqlDatabase。SqlDatabase有一个SqlClientPermission属性,它在Castle Windsor(Moq使用)中不起作用。我必须显式地指示Castle忽略SqlClientPermission属性以使测试正常工作(参见下面示例中的第1行)。下面是一个单元测试示例(借用stevenh的例子)。

        [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
  •  2
  •   holsee    14 年前

    我用假调皮的 http://code.google.com/p/fakeiteasy/

    我创建了一个SqlDatabase的mock(使用更友好的构造函数从数据库继承)将其传递给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);
    }
    
        3
  •  1
  •   Chris Tavares    14 年前

    数据库是一个抽象基类,而DbProviderFactory也是抽象的,所以您可以模拟它们。只要模拟了对数据库类型调用的操作(几乎所有操作都是虚拟的,所以在那里应该可以),实际上就不需要在提供程序工厂中执行任何操作。连接字符串可以是空的、空的或者其他的。

        4
  •  1
  •   Joshua Ramirez    14 年前