Rhino模拟:如何模拟无参数方法中的数据库调用

本文关键字:模拟 方法 参数 数据库 调用 何模拟 Rhino | 更新日期: 2023-09-27 18:11:37

我正在为ASP编写单元测试。. NET MVC应用程序,使用NUnit和Rhino mock。我在测试这个方法时遇到了一些麻烦:

public void Install()
    {
        Database.SetInitializer<DraftOrderObjectContext>(null);
        var dbScript = CreateDatabaseInstallationScript();
        Database.ExecuteSqlCommand(dbScript);
        SaveChanges();
    }

澄清一下,Database不是引用一个本地对象。第一个"Database.SetInitializer…"指的是:

System.Data.Entity.Database

和第二个"Database.ExecuteSqlCommand…"指的是:

System.Data.Entity.DbContext.Database

由于该方法不返回任何东西,我认为这将是足够的模拟和验证Database.ExecuteSqlCommand(dbScript);至少被调用过一次

我以前已经这样做过了,但那涉及到将数据库上下文传递给方法,这很容易模拟,但是,在本例中没有参数。我需要找到一种方法来模拟'数据库'。


我试过直接分配一个模拟,像这样:

System.Data.Entity.DbContext.Database = MockRepository.GenerateMock<System.Data.Entity.DbContext.Database>();

,但这会破坏语法,因为属性是只读的。


我也试过像这样嘲笑DbContext:

System.Data.Entity.DbContext instance = MockRepository.GenerateMock<System.Data.Entity.DbContext>();
        instance.Expect(someCaller => someCaller.Database.ExecuteSqlCommand("sql"))
            .IgnoreArguments()
            .Return(1)
            .Repeat.Times(1);

但我得到一个运行时错误说DbContext.getHashCode()必须返回一个值。然后,我尝试存根getHashCode方法,使其返回一些东西,但没有效果。


我对嘲笑还是相当陌生的,所以我可能在这里错过了一些基本的概念。如果是这样的话,我很抱歉。任何帮助都非常感激!

Rhino模拟:如何模拟无参数方法中的数据库调用

恐怕这里唯一值得给出的答案是必须修改代码以使其更适合测试。试图为调用static类、属性或方法的方法编写单元测试并不是一项值得的任务。您认为您可能在这里错过了一个基本概念,这可能就是它:static是单元测试的最大敌人,而集体智慧是,投入大量精力测试使用静态资源的东西没有多大意义。只要重构代码。

如果重构代码真的是不可能的,那么为什么你需要单元测试它(这不是一个反问问题,请评论)?如果您担心需要模拟这些对象作为其他测试的一部分,那么您应该用一个测试友好的接口来包装这些邪恶的、不可修改的代码,并模拟它。