问题
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:
Interface and concrete class to be substituted. Notice,
MyConcreteClass.MyMethod()
returnsfalse
:public interface IMyInterface { bool MyMethod(string arg); } public class MyConcreteClass : IMyInterface { public bool MyMethod(string arg) { return false; } }
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); } }
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. } }
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