简体   繁体   English

如何通过Nunit模拟新对象的构造

[英]How to Mock construction of new objects through Nunit

I want to write a nunit test to test a method but I am not able to mock an object instantiated inside that method. 我想编写一个nunit测试来测试一个方法,但是我无法模拟在该方法中实例化的对象。

Here is the code: 这是代码:

public class Converter()
{ 
    public void modifyScore(string convertTo){
      ScoreConverter scoreConverter;
      if(convertTo.Equals("decimal"){    
           scoreConverter = new DecimalScoreConverter();
           scoreConverter.determineScore();
      }
      else{
           scoreConverter = new IntegerScoreConverter();
           scoreConverter.determineScore();
      }
}

I want to write a test for modifyScore and want to test which object's method has called. 我想为ModifyScore编写测试,并想测试调用了哪个对象的方法。

How can I test this method using nunit? 如何使用nunit测试此方法?

First of all you should start working against abstractions. 首先,您应该开始反对抽象。 I think this is needed for all mock frameworks. 我认为所有模拟框架都需要这样做。 From the info you gave me, and a couple of assumptions: 根据您提供给我的信息以及一些假设:

Anyway, here we go: 无论如何,我们开始:

public Interface IConverter
{ 
    IScoreConverter ScoreConverter { get; set; };//use constructorinjection instead
    void ModifyScore(string convertTo);
}

public Interface IScoreConverter
{ 
    DetermineScore();
}

I would recommend taking a look at MoQ . 我建议您看看起订量

You need to figure out what you want to be returned by the inner object. 您需要弄清楚内部对象要返回的内容。 For now you don't return any value from ModifyScore, so you have nothing to test. 目前,您没有从ModifyScore返回任何值,因此无需进行任何测试。

If you would return eg a string, the test could look like this: 如果返回例如字符串,则测试可能如下所示:

var scoreConverterResponse = "theStringYouWantToBeReturned" 

var scoreConverterMock = new Mock<IScoreConverter>();
scoreConverterMock.Setup(sc => sc.DetermineScore())
  .Returns(scoreConverterResponse);

scoreConverterMock.Verify(sc => sc.DetermineScore(It.IsAny<string>()), Times.AtLeastOnce());

I fixed the naming conventions toom ie CamelCase methods. 我修复了命名约定toom即CamelCase方法。 I wrote this on the fly, so I apologise if there are compile errors. 我是即时编写的,因此如果出现编译错误,我深表歉意。

Unit tests are mostly based on state change. 单元测试主要基于状态更改。 So, the natural course is to: 因此,自然的过程是:

  • Do something on a class 在课堂上做点事
  • Test whether the state of the class changed as expected 测试类的状态是否按预期更改

Maybe you can consider a change in your code to test the type of scoreConverter: 也许您可以考虑更改代码以测试scoreConverter的类型:

public class Converter
{ 
    public ScoreConverter scoreConverter { get; set; }

    public void modifyScore(string convertTo){

      if(convertTo.Equals("decimal"){    
           scoreConverter = new DecimalScoreConverter();
      }
      else{
           scoreConverter = new IntegerScoreConverter();
      }
      scoreConverter.determineScore();
}

Your test can then execute the modifyScore() method, and then Assert the type of scoreConverter variable. 然后,您的测试可以执行ModifyScore()方法,然后断言scoreConverter变量的类型。

If you don't want to make the property public, another option is to make it internal and then add the InternalsVisibleToAttribute , or maybe to use a Factory class and then mock it in the test, as amcdermott pointed out. 如果您不想公开该属性,则另一个选择是将其设置为内部,然后添加InternalsVisibleToAttribute ,或者使用Factory类,然后在测试中对其进行模拟,如amcdermott所指出的。

Greetings! 问候!

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

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