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方法,使其返回一些东西,但没有效果。
我对嘲笑还是相当陌生的,所以我可能在这里错过了一些基本的概念。如果是这样的话,我很抱歉。任何帮助都非常感激!
恐怕这里唯一值得给出的答案是必须修改代码以使其更适合测试。试图为调用static
类、属性或方法的方法编写单元测试并不是一项值得的任务。您认为您可能在这里错过了一个基本概念,这可能就是它:static
是单元测试的最大敌人,而集体智慧是,投入大量精力测试使用静态资源的东西没有多大意义。只要重构代码。
如果重构代码真的是不可能的,那么为什么你需要单元测试它(这不是一个反问问题,请评论)?如果您担心需要模拟这些对象作为其他测试的一部分,那么您应该用一个测试友好的接口来包装这些邪恶的、不可修改的代码,并模拟它。