[英]Rhino Mocks: How to Mock a Database call in a Parameterless Method?
我正在使用NUnit和Rhino Mocks在C#中编写ASP.NET MVC应用程序的单元测试。 我在测试此方法时遇到了一些麻烦:
public void Install()
{
Database.SetInitializer<DraftOrderObjectContext>(null);
var dbScript = CreateDatabaseInstallationScript();
Database.ExecuteSqlCommand(dbScript);
SaveChanges();
}
只是为了澄清,数据库不是指本地对象。 第一个“ 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
是单元测试的最大敌人,而集体的智慧是,在测试使用静态资源的事物上花很多精力是没有多大意义的。 只需重构代码即可。
如果重构代码确实是不可能的,那么为什么还要对它进行单元测试(这不是一个反问,请发表评论)? 如果您担心需要在其他测试中模拟这些对象,则应使用友好的测试接口包装这些邪恶的,不可修改的代码,并对其进行模拟。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.