简体   繁体   English

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

[英]Rhino Mocks: How to Mock a Database call in a Parameterless Method?

I am writing unit tests for an ASP.NET MVC application in C# using NUnit and Rhino Mocks. 我正在使用NUnit和Rhino Mocks在C#中编写ASP.NET MVC应用程序的单元测试。 I am having some trouble testing this method: 我在测试此方法时遇到了一些麻烦:

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

        Database.ExecuteSqlCommand(dbScript);
        SaveChanges();
    }

Just to clarify, Database is not referring to a local object. 只是为了澄清,数据库不是指本地对象。 The first one "Database.SetInitializer..." refers to: 第一个“ Database.SetInitializer ...”指的是:

System.Data.Entity.Database

and the second "Database.ExecuteSqlCommand..." refers to: 第二个“ Database.ExecuteSqlCommand ...”是指:

System.Data.Entity.DbContext.Database

Since the method does not return anything, I figured it would be sufficient to make a mock and verify that Database.ExecuteSqlCommand(dbScript); 由于该方法不返回任何内容,因此我认为进行模拟并验证Database.ExecuteSqlCommand(dbScript);就足够了。 was called at least once. 至少被叫过一次。

Now I've done this before, but that involved passing a database context to the method, which is easy enough to mock, however, in this case there are no parameters. 现在,我已经做完了,但是涉及到将数据库上下文传递给方法,这很容易模拟,但是在这种情况下,没有参数。 I need to somehow find a way to mock 'Database'. 我需要以某种方式找到模拟“数据库”的方法。


I have tried straight up assigning a mock like so: 我已经尝试直接分配一个模拟,像这样:

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

but that breaks syntax because the property is read only. 但这破坏了语法,因为该属性是只读的。


I have also tried mocking DbContext like so: 我也尝试过像这样模拟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);

but I get a runtime error saying DbContext.getHashCode() must return a value. 但是我收到一个运行时错误消息,说DbContext.getHashCode()必须返回一个值。 I then tried stubbing the getHashCode method to make it return something but that had no effect. 然后,我尝试对getHashCode方法进行存根处理,以使其返回某些内容,但这无效。


I am still fairly new to mocking so I may be missing some fundamental concept here. 我对模拟还很陌生,因此这里可能缺少一些基本概念。 My apologies if that is the case. 如果是这样,我表示歉意。 Any help is much appreciated! 任何帮助深表感谢!

I'm afraid the only answer worth giving here is that the code must be modified to be more test-friendly. 恐怕唯一值得在这里给出的答案是必须对代码进行修改以使其更加易于测试。 Trying to write unit tests for methods that make calls to static classes, properties or methods is not a rewarding or worthwhile task. 尝试为调用static类,属性或方法的方法编写单元测试不是一项有价值的任务。 You suggest that you may be missing a fundamental concept here and this may be it: static is unit testing's worst enemy and the collective wisdom is that there isn't much point putting a lot of effort into testing things that use static resources. 您建议您可能在这里遗漏了一个基本概念,可能就是这样: static是单元测试的最大敌人,而集体的智慧是,在测试使用静态资源的事物上花很多精力是没有多大意义的。 Just refactor the code. 只需重构代码即可。

If refactoring the code is truly impossible then why would you need to unit test it (this is not a rhetorical question, please comment)? 如果重构代码确实是不可能的,那么为什么还要对它进行单元测试(这不是一个反问,请发表评论)? If the concern is that you need to mock these objects as part of other tests, then you should wrap the evil, unmodifiable code with a test friendly interface and mock that instead. 如果您担心需要在其他测试中模拟这些对象,则应使用友好的测试接口包装这些邪恶的,不可修改的代码,并对其进行模拟。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM