简体   繁体   中英

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.

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.

How can I test this method using 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.

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. 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:

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.

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.

Greetings!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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