NSubstitute: Mock method is not returning expected result

二次信任 提交于 2019-12-23 21:18:12

问题


I'm new to NSubstitute, mocking, and unit testing in general.

I'm trying to use NSubstitute to remove some dependencies I have in my class under test, but methods in the mock objects are not behaving as I expect based on how I configured them. Here is an example I created in Visual Studio:

  1. Interface and concrete class to be substituted. Notice, MyConcreteClass.MyMethod() returns false:

    public interface IMyInterface
    {
        bool MyMethod(string arg);
    }
    
    public class MyConcreteClass : IMyInterface
    {
        public bool MyMethod(string arg)
        {
            return false;
        }
    }
    
  2. My class under test:

    public class MyTestedClass
    {
        private IMyInterface _concrete;
    
        public MyTestedClass()
        {
            _concrete = new MyConcreteClass();
        }
    
        public MyTestedClass(IMyInterface mock)
        {
            _concrete = mock;
        }
    
        public bool MyConcreteMethod(string arg)
        {
            return _concrete.MyMethod(arg);
        }
    }
    
  3. My unit test class for MyTestedClass:

    [TestClass]
    public class UnitTest1
    {
        [TestMethod]
        public void Given_MyMethodIsUsingAMock_ShouldReturnTrue()
        {
            // Arrange
            var myMock = Substitute.For<IMyInterface>();
            myMock.MyMethod("blah").Returns(true);
            var myTestedObject = new MyTestedClass(myMock);
    
            // Act
            var result = myTestedObject.MyConcreteMethod("blah blah");
    
            // Assert
            Assert.AreEqual(result, true); // This assertion fails!
        }
    
        [TestMethod]
        public void Given_MyMethodIsNotMock_ShouldReturnFalse()
        {
            // Arrange
            var myTestedObject = new MyTestedClass();
    
            // Act
            var result = myTestedObject.MyConcreteMethod("blah blah");
    
            // Assert
            Assert.AreEqual(result, false); // This assertion passes.
        }
    }
    
  4. Test results show that Given_MyMethodIsUsingAMock_ShouldReturnTrue() fails:

    MyUnitTests (2 tests) [0:00.190] Failed: 1 test failed
     MyUnitTests (2 tests) [0:00.190] Failed: 1 test failed
      UnitTest1 (2 tests) [0:00.190] Failed: 1 test failed
       Given_MyMethodIsNotMock_ShouldReturnFalse [0:00.000] Success
       Given_MyMethodIsUsingAMock_ShouldReturnTrue [0:00.189] Failed
    Assert.AreEqual failed. Expected:<False>. Actual:<True>. 
       at MyUnitTests.UnitTest1.Given_MyMethodIsUsingAMock_ShouldReturnTrue() in "c:\MyWorkspace\projects\NSubstituteMocking\MyUnitTests\UnitTest1.cs":line 23
    

It looks like I'm missing a trivial configuration, but it is eluding me.


回答1:


The MyMethod is arranged to return true when given "blah"

myMock.MyMethod("blah").Returns(true);

but is then provide it with "blah blah" when being acted upon.

var result = myTestedObject.MyConcreteMethod("blah blah");

As the expected/arranged parameter did not match, the mock did not behave as configured.

Provide the mock with what it expects to receive for it to behave as expected.

[TestMethod]
public void Given_Blah_MyConcreteMethod_ShouldReturnTrue() {
    // Arrange
    var myMock = Substitute.For<IMyInterface>();
    var arg = "blah";
    var expected = true;
    myMock.MyMethod(arg).Returns(expected);
    var myTestedObject = new MyTestedClass(myMock);

    // Act
    var actual = myTestedObject.MyConcreteMethod(arg);

    // Assert
    Assert.AreEqual(expected, actual); // This should pass
}

Note the use of variables to store the provided and expected values so that mistakes can be reduced when exercising the test.



来源:https://stackoverflow.com/questions/47647706/nsubstitute-mock-method-is-not-returning-expected-result

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!