NSubstitute not responding to Received() assertation - c#

I have a test which mocks a non-interface object with a constructor that takes parameters:
[Test]
public void Test()
{
var myObject = Substitute.For<MyObject>("param1", "param2");
_sut.DoSomething(myObject);
myObject.Received().SomeMethodWhichIsCalled();
}
This passes and when I debug the test, I can see SomeMethodWhichIsCalled() on MyObject is executed correctly.
However I've now realised this assert does nothing, because I can add the below in:
[Test]
public void Test()
{
var myObject = Substitute.For<MyObject>("param1", "param2");
_sut.DoSomething(myObject);
myObject.DidNotReceive().SomeMethodWhichIsCalled();
myObject.Received().SomeMethodWhichIsCalled();
}
And the test still passes...
Is this a side effect of mocking classes and not interfaces?

You can mock only virtual members. The mocking-framework simply overrides the virtual members for you similar to this:
class MyMock : MyObject
{
override void SomeMethodWhichIsCalled()
{
throw new Exception("Method was called");
}
}
As your method is not virtual the framework isn´t able to override it and thus the actual method SomeMethodWhichIsCalled of MyObject is called, which never throws the exception.
There´s not much you can do about this, unless you can make the method virtual. You could try to access some internal state via reflection, but that highly depends on what SomeMethodWhichIsCalled does. In particular it´s only a dirty hack.

Related

Avoid calling a non-virtual method in a unit test

I'm tasked with writing some tests to one of our codebases.
Now I have this class:
```
public class A
{
public void method_1()
{
this.method_2();
// Do something
}
public void method_2()
{
Environment.CurrentDirectory = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
// Do something
}
}
```
Now I'm trying to write a test for method_1 without invoking method_2 and getting NullReferenceException.
[TestClass]
public class MyTestClass
{
[TestMethod]
public void MyTestMethod()
{
// Ignore the call: Assembly.GetEntryAssembly() because it returns null>
new A().method_1();
}
Any suggestion?
EDIT:
I'm not allowed to change the code.
Without the possibility to override/mock the logic inside method_2 there is not much you can do.
If it is your own codebase I suggest to move the call to Assembly.GetEntryAssembly().Location to some helper method which you can override for the tests.
Assuming you cannot change anything to the code, you can use MS Fakes to mock out static methods like DateTime.Now. Should also work on Assembly.GetEntryAssembly().
I'm not a big fan of MS Fakes though, had a few too many problems with it in the past. If you can make a small change to the code, you can make the method_2 virtual and do something like this:
public class MyTestA : A
{
public override void method_2()
{
//Do nothing
}
}
You can then write your tests against MyTestA.
Of course, putting the code in method 2 in a new class/interface and mock that as a dummy interface is an even cleaner solution.

How do I setup MOQ to Set property Objects and verify the method [duplicate]

It is my understanding that I can test that a method call will occur if I call a higher level method, i.e.:
public abstract class SomeClass()
{
public void SomeMehod()
{
SomeOtherMethod();
}
internal abstract void SomeOtherMethod();
}
I want to test that if I call SomeMethod() then I expect that SomeOtherMethod() will be called.
Am I right in thinking this sort of test is available in a mocking framework?
You can see if a method in something you have mocked has been called by using Verify, e.g.:
static void Main(string[] args)
{
Mock<ITest> mock = new Mock<ITest>();
ClassBeingTested testedClass = new ClassBeingTested();
testedClass.WorkMethod(mock.Object);
mock.Verify(m => m.MethodToCheckIfCalled());
}
class ClassBeingTested
{
public void WorkMethod(ITest test)
{
//test.MethodToCheckIfCalled();
}
}
public interface ITest
{
void MethodToCheckIfCalled();
}
If the line is left commented it will throw a MockException when you call Verify. If it is uncommented it will pass.
No, mock testing assumes you are using certain testable design patterns, one of which is injection. In your case you would be testing SomeClass.SomeMethod and SomeOtherMethod must be implemented in another entity which needs to be interfaced.
Your Someclass constructor would look like New(ISomeOtherClass). Then you would mock the ISomeOtherClass and set expectation on its SomeOtherMethod to be called and verify the expectation.
Even though I agree that the #Paul's answer is the recommended way to go I just want to add one alternative way which is provided by moq off the self.
Since SomeClass is abstract it is indeed mockable, but public void SomeMehod() isn't. The point is to find the way to mock and somehow invoke that method and then using CallBase propagate the call to the SomeOtherMethod(). It might sound as a hack but it is simple in essence. It could be used in the case if the proposed refactoring is not possible.
// This class is used only for test and purpose is make SomeMethod mockable
public abstract class DummyClass : SomeClass
{
public virtual void DummyMethod() => base.SomeMethod();
}
Then you could setup DummyMethod() to propagate the call by setting CallBase flag.
//Arrange
var mock = new Mock<DummyClass>();
mock.Setup(m => m.DummyMethod()).CallBase();
//Act
mock.Object.SomeMethod();
//Assert
mock.Verify(m => m.SomeOtherMethod(), Times.Once);

Moq tell if function was called [duplicate]

I have a base class:
public abstract class MyBaseClass
{
protected virtual void Method1()
{
}
}
and a derived class:
public class MyDerivedClass : MyBaseClass
{
public void Method2()
{
base.Method1();
}
}
I want to write a unit test for Method2 to verify that it calls Method1 on the base class. I'm using Moq as my mocking library. Is this possible?
I came across a related SO link:
Mocking a base class method call with Moq
in which the 2nd answer suggests it can be achieved by setting CallBase property to true on the mock object. However it's not clear how this would enable the call to the base class method (Method1 in the above example) to be verified.
Appreciate any assistance with this.
Unit tests should verify behavior, not implementation. There are several reasons for this:
The results are the goal, not how you get the results
Testing results allows you to improve the implementation without re-writing your tests
Implementations are harder to mock
You might be able to put in hooks or create mocks that verify that the base method was called, but do you really care how the answer was achieved, or do you care that the answer is right?
If the particular implementation you require has side effects that you can verify, then that is what you should be validating.
Mocking the base class from the perspective of the derived class is not possible. In your simple example, I would suggest one of the two options.
Option 1: In the event that MyDerivedClass really shouldn't care what MyBaseClass is up to, then use dependency injection! Yay abstraction!
public class MyClass
{
private readonly IUsedToBeBaseClass myDependency;
public MyClass(IUsedToBeBaseClass myDependency){
_myDependency = myDependency;
}
public void Method2()
{
_myDependency.Method1();
}
}
Elsewhere in test land...
[TestClass]
public class TestMyDependency {
[TestMethod]
public void TestThatMyDependencyIsCalled() {
var dependency = new Mock<IUsedToBeBaseClass>();
var unitUnderTest = new MyClass(dependency.Object);
var unitUnderTest.Method2();
dependency.Verify(x => x.Method1(), Times.Once);
}
}
Option 2: In the event that MyDerivedClass NEEDS to know what MyBaseClass is doing, then test that MyBaseClass is doing the right thing.
In alternative test land...
[TestClass]
public class TestMyDependency {
[TestMethod]
public void TestThatMyDependencyIsCalled() {
var unitUnderTest = new MyDerivedClass();
var unitUnderTest.Method2();
/* verify base class behavior #1 inside Method1() */
/* verify base class behavior #2 inside Method1() */
/* ... */
}
}
What you're describing is not a test of your code, but a test of the behavior of the language. That's fine, because it's a good way to ensure that the language behaves the way we think it does. I used to write lots of little console apps when I was learning. I wish I'd known about unit testing then because it's a better way to go about it.
But once you've tested it and confirmed that the language behaves the way you expect, I wouldn't keep writing tests for that. You can just test the behavior of your code.
Here's a real simple example:
public class TheBaseClass
{
public readonly List<string> Output = new List<string>();
public virtual void WriteToOutput()
{
Output.Add("TheBaseClass");
}
}
public class TheDerivedClass : TheBaseClass
{
public override void WriteToOutput()
{
Output.Add("TheDerivedClass");
base.WriteToOutput();
}
}
Unit test
[TestMethod]
public void EnsureDerivedClassCallsBaseClass()
{
var testSubject = new TheDerivedClass();
testSubject.WriteToOutput();
Assert.IsTrue(testSubject.Output.Contains("TheBaseClass"));
}

Does the methods in mocked objects work?

Does the methods in mocked objects work ?
For example if I have an object with method name Method1 and I mock the object :
var mockobject= Mock<myobject>();
Does the next call to method work :
mockobject.Method1()
?
It is a question to clarify about the mock objects.
If you're mocking a concrete class or abstract class with method implementations. For virtual methods you have two options.
Create a Setup to fake the method call
mockobject.Setup(x => x.Method1()).Returns(true);
Set CallBase = true on the mock to invoke the concrete behavior of the Method1 method.
mockobject.CallBase = true;
Usage:
public class MyClass
{
public virtual int MyMethod()
{
return 5;
}
}
[Test]
public void ShouldGiveMeZero()
{
var mockMyClass = new Mock<MyClass>();
// returns default(int)
Assert.AreEqual(0, mockMyClass.Object.MyMethod());
}
[Test]
public void ShouldGiveMeFive()
{
var mockMyClass = new Mock<MyClass>();
mockMyClass.CallBase = true;
// calls concrete implementation
Assert.AreEqual(5, mockMyClass.Object.MyMethod());
}
[Test]
public void ShouldGiveMeSix()
{
var mockMyClass = new Mock<MyClass>();
mockMyClass.Setup(x => x.MyMethod()).Returns(6);
// calls Setup
Assert.AreEqual(6, mockMyClass.Object.MyMethod());
}
First, note that your example will never compile:
mockobject.Method1()
Method1 doesn't live on the mock object itself--it lives in the underlying mocked object instance:
mockobject.Object.Method1();
The behavior of that call depends on what MockBehavior you're using (Strict or Loose). It also depends on if the method you're calling is marked virtual or not.
If Method1 is non-virtual, the implementation for the actual type will be used, since Mock cannot mock non-virtual methods.
For example, if MyObject is defined like this:
public class MyObject
{
public int Method1()
{
return 1;
}
}
mockObject.Object.Method1() will return 1 since Mock is unable to provide any other implementation for the method.
Now, if Method1 is declared virtual:
public virtual int Method1()
{
return 1;
}
The MockBehavior comes into play. The default is MockBehavior.Loose, which means that methods not defined using the .Setup method will return default(T) where T is the return type of the method. So the following:
var mockObject = new Mock<MyObject>(MockBehavior.Default);
int result = mockObject.Object.Method1();
Will always return 0 unless you use .Setup to make it return otherwise. You can also specify CallBase = true on the Mock<MyObject> instance and the base implementation will be invoked for methods that aren't defined using .Setup.
If you're using MockBehavior.Strict, unimplemented methods will throw an exception:
var mockObject = new Mock<MyObject>(MockBehavior.Strict);
int result = mockObject.Object.Method1(); // Always throws an exception
If you look at the quickstart guide there are simple examples to get you going, e.g.
var mock = new Mock<IFoo>();
mock.Setup(foo => foo.DoSomething("ping")).Returns(true);
Note the call to Setup to make the mock/fake actually do something.
In this situation you have created the default stub for Method1. If you were to create this by hand you would have code similar to:
public class MyObject {
public virtual void Method1() {
throw new NotImplementedException();
}
}
Your stub would be:
public class Stub : MyObject {
public override void Method1() {
}
}
So now instead of getting a NotImplementedException you have an instance of MyObject that will allow you to call Method1 regardless of its original implementation.
Note my usage of virtual. Without the usage of virtual there is nothing for Moq to override.
This is actually one of my favorite usages of mocking. Many people go overboard with interfaces for everything "for mocking". The most baseline scenarios only require methods to be virtual. In general I mark nearly every public method I create as virtual. If a public method cannot be virtual, it is likely a violation of the Open Closed Principle.

Rhino Mocks Partial Mock

I am trying to test the logic from some existing classes. It is not possible to re-factor the classes at present as they are very complex and in production.
What I want to do is create a mock object and test a method that internally calls another method that is very hard to mock.
So I want to just set a behaviour for the secondary method call.
But when I setup the behaviour for the method, the code of the method is invoked and fails.
Am I missing something or is this just not possible to test without re-factoring the class?
I have tried all the different mock types (Strick,Stub,Dynamic,Partial ect.) but they all end up calling the method when I try to set up the behaviour.
using System;
using MbUnit.Framework;
using Rhino.Mocks;
namespace MMBusinessObjects.Tests
{
[TestFixture]
public class PartialMockExampleFixture
{
[Test]
public void Simple_Partial_Mock_Test()
{
const string param = "anything";
//setup mocks
MockRepository mocks = new MockRepository();
var mockTestClass = mocks.StrictMock<TestClass>();
//record beahviour *** actualy call into the real method stub ***
Expect.Call(mockTestClass.MethodToMock(param)).Return(true);
//never get to here
mocks.ReplayAll();
//this is what i want to test
Assert.IsTrue(mockTestClass.MethodIWantToTest(param));
}
public class TestClass
{
public bool MethodToMock(string param)
{
//some logic that is very hard to mock
throw new NotImplementedException();
}
public bool MethodIWantToTest(string param)
{
//this method calls the
if( MethodToMock(param) )
{
//some logic i want to test
}
return true;
}
}
}
}
MethodToMock is not virtual and therefore can't be mocked. What you want to do is possible with a partial mock (I've done it in cases similar to yours), but the method you want to mock out must be either part of an interface implementation or be marked virtual. Otherwise, you can't mock it with Rhino.Mocks.
I recommend not mocking methods in the class under test, but your situation may be unique in that you can't refactor the class to make it easier to test at present. You might try explicitly making a delegate to prevent the method from being invoked when setting up the call.
Expect.Call( delegate { mockTestClass.MethodToMock(param) } ).Return(true);
Or, switch to using the AAA syntax, omitting the deprecated constructs.
[Test]
public void Simple_Partial_Mock_Test()
{
const string param = "anything";
var mockTestClass = MockRepository.GenerateMock<TestClass>();
mockTestClass.Expect( m => m.MethodToMock(param) ).Return( true );
//this is what i want to test
Assert.IsTrue(mockTestClass.MethodIWantToTest(param));
mockTestClass.VerifyAllExpectations();
}

Categories

Resources