Moq testing if method1 calls second method2 in same class - c#

I'm new to Moq
I read a lot about Moq testing and that you shouldn't test your mock object, instead you should use Moq to stub dependencies and make it to act like you want to. But now I am asking myself, how can you test if a method be called from another method in the same class, like this code:
public class A // --> class i want to test
{
public virtual void TestMethod() // --> does it call testmethod2
{
TestMethod2();
}
public virtual void TestMethod2()
{
// Do something
}
}
I thought I can write the Unittest like this:
[TestMethod]
public void MyTestMethod()
{
Mock<A> aMock = new Mock<A>();
aMock.Verify(o => o.TestMethod2(), Times.Once);
aMock.TestMethod();
aMock.VerifyAll();
}
But is this valid? Thank you for all good answers!

Moq is only able to mock out methods which are virtual (or provide mock implementations for interfaces). If you try a Setup or Verify on a non-virtual member, you'll get the error
Invalid verify on a non-virtual member: m => m.TestMethod2()
In your case, you would need to change TestMethod2 to virtual, i.e.
public virtual void TestMethod2()
Which can then be tested:
var aMock = new Mock<A>();
aMock.Object.TestMethod();
aMock.Verify(m => m.TestMethod2(), Times.Once);
As you've suggested, testing whether a class calls methods internal to itself is a smell, indication that you're either
Testing internal implementation detail (e.g. if TestMethod2() was private, it's none of our business to even know about it).
Or, an indication that the Class / System under test is in need of refactoring into multiple classes, which should be loosely coupled, and hence can be isolated and better testable.
Note
You can't Verify a call before you've invoked the method on the SUT that you want to test, i.e. move the Verify to after the invocation of .TestMethod() as I've done.
Although you could change your code to use the Setup + VerifyAll approach to testing, i.e. ensuring that everything you've setup is actually invoked:
aMock.Setup(m => m.TestMethod2());
aMock.Object.TestMethod();
aMock.VerifyAll();
There is however debate around whether the usage of VerifyAll violates AAA principals (since you're also in effect specifying the Verify criteria in the Arrange piece), and I've also found that this approach makes it impossible to refactor and DRY up Mock setups in large scale tests, and you also lose some of the finer level of checking (e.g. Times.Once).

Related

How to write unit test for private method in c# using moq framework?

I want to write unit test for private method in C# using moq framework, I've search in StackOverFlow and Google, but I cannot find the expected result. Please help me if you can.
You can't, at least not with Moq.
But more importantly, you shouldn't.
First off, you don't test methods, you test behaviours. Second, in order to test behaviours, you exercise a type's public API and verify the outcomes of that exercise.
Private methods are implementation details. You don't want to verify how things get done, you want to verify that things do get done.
In the AssemblyInfo.cs of your project add
[assembly: InternalsVisibleTo("Namespace.OfYourUnitTest.Project")]
then you make the method internal instead of private.
It has the benefit of avoiding to make it public.
However as pointed by dcastro, some people strongly disagree with this way of testing.
Perhaps you shouldn't (see other answers for why), but you can do this using Microsoft's Visual Studio Test Tools. A simplified example is given below.
Given the following class which you want to test:
public class ClassToTest
{
private int Duplicate(int n)
{
return n*2;
}
}
You can use the following code to test the private Duplicate method:
using Microsoft.VisualStudio.TestTools.UnitTesting;
// ...
[TestMethod]
public void MyTestMethod()
{
// Arrange
var testClass = new ClassToTest();
var privateObject = new PrivateObject(testClass);
// Act
var output = (int) privateObject.Invoke("Duplicate", 21);
// Assert
Assert.AreEqual(42, output);
}
Simply, you don't. Private methods are not visible to other classes.
There are a number of ways around this:
Treat the private as part of the method you're testing, cover it in their unit tests. Think of the public methods as black boxes and test their operations.
Make it protected and inherit your test class from the class you're testing (or use a partial - same idea)
Make it public (which if you're coding to an interface doesn't actually expose it to your consumers)
For public methods (option three) it is possible to partial mock the class where you can replace the method. In Moq you can do this like this:
var moq = new Mock<MyClass>();
moq.CallBase = true;
moq.Setup(x => x.MyPublicMethodToOverride()).Returns(true);
There are more details here.
Moq supports mocking protected methods. Changing the methods to protected, instead of private, would allow you to mock their implementation.
The following is from Moq Quickstart Documentation (deep link):
Setting expectations for protected members (you can't get IntelliSense
for these, so you access them using the member name as a string).
Assuming the following class with a protected function should be
mocked:
public class CommandBase {
protected virtual int Execute(); // (1)
protected virtual bool Execute(string arg); // (2)
}
// at the top of the test fixture
using Moq.Protected;
// In the test, mocking the `int Execute()` method (1)
var mock = new Mock<CommandBase>();
mock.Protected()
.Setup<int>("Execute")
.Returns(5);
// If you need argument matching, you MUST use ItExpr rather than It
// planning on improving this for vNext (see below for an alternative in Moq 4.8)
// Mocking the `bool Execute(string arg)` method (2)
mock.Protected()
.Setup<bool>("Execute",
ItExpr.IsAny<string>())
.Returns(true);
Moq 4.8 and later allows you to set up protected members through a
completely unrelated type that has the same members and thus provides
the type information necessary for IntelliSense to work. Pickin up the
example from the bullet point above, you can also use this interface
to set up protected generic methods and those having by-ref
parameters:
// Completely unrelated Interface (CommandBase is not derived from it) only created for the test.
// It contains a method with an identical method signature to the protected method in the actual class which should be mocked
interface CommandBaseProtectedMembers
{
bool Execute(string arg);
}
mock.Protected().As<CommandBaseProtectedMembers>()
.Setup(m => m.Execute(It.IsAny<string>())) // will set up CommandBase.Execute
.Returns(true);

How to skip over a method call inside that is inside the method being unit tested

I have a method call that I am unit testing. Inside that method call it makes a call to a method that is going to throw an error because it is trying to talk to a device that will not be available when the unit test is running. Is there a way to avoid that internal method call from being called?
Environment: C# Visual Studio 2010 unit testing within IDE
If you're unit testing a class with external dependencies then you must isolate the external dependancies using an interface which is injected in.
interface IDevice
{
void Run();
}
interface IDeviceOperator
{
void Operate();
}
class DeviceOperator : IDeviceOperator
{
private readonly IDevice _device;
public DeviceOperator(IDevice device)
{
_device = device;
}
public void Operate()
{
_device.Run();
// test other stuff here
}
}
[TestFixture]
public class DeviceOperatorTests
{
[Test]
public void Test_DeviceOperator_Operate()
{
IDevice device = A.Fake<IDevice>(); // Using FakeItEasy 3rd party mocking framework syntax
DeviceOperator deviceOperator = new DeviceOperator(device);
deviceOperator.Operate();
}
}
When doing unit testing you have to create mocks or stubs for all your external dependencies. A framework that could help you with that is Moq (it is plenty of mock frameworks if you want to explore).
These mock or stubs are just facades providing necessary interactions and data to pass your tests.
We may be able to help you more if you provide more details about that unavailable device.
There's probably a better way, but once or twice I've been in this situation where a method calls another, complicated method, and put an optional parameter at the end of the method you're testing like
public void DoSomething(int number, bool skipMethod= false)
{
if(!skipMethod)
MethodThatWillBreak();
{
So that in the normal course of running, it'll be fine, but in your unit test you can do
DoSomething(2,true);
But really, it suggests that you need to do some refactoring of your code, because your unit test should only be hitting one "unit". If you can test the method without calling the MethodThatWillBreak then what is it doing there in the first place.
Check out Working Effectively with Legacy Code book by Michael Feathers - it have a lot of suggestions on dealing with code that does not have unit test yet.
Possible approaches covered in the book:
extract dependency in interface - ideal approach (see jamespconnor's answer)
use flag to bypass call (see Colm Prunty's answer)
extract that call into virtual method and override in derived class used in unit test
pass delegate (may be less impact than full interface/derivation)
Sample for deriving from the class:
public class WithComplexDependency
{
public void DoSomething()
{
// Extract original code into a virtual protected method
// dependency.MethodThatWillBreak();
CallMethodThatWillBreak();
}
virtual protected void CallMethodThatWillBreak()
{
dependency.MethodThatWillBreak();
}
}
in test code derive from the class and provide own implementation:
public class WithMockComplexDependency : WithComplexDependency
{
// may also need to add constructor to call original one.
override protected void CallMethodThatWillBreak()
{
// do whatever is needed for your test
}
}
...
WithComplexDependency testObject = new WithMockComplexDependency();
testObject.DoSomething(); // now does not call dependency.MethodThatWillBreak()
...
To unit test correctly you should decouple the comunication with the device from the class you want to test! Abstract the partetalking to the device in another class implementing an interface, inject the communication class in the ctor of the object under test, now you can inject a mock implementation from outside and avoid the errore,the mmock implementation can also log call made to it or respond in a predefined way easing test.
Read a out dependency injection and inversion of control
Typically you would extract external dependencies from the class you're testing and will swap them with fake ones in your unit test. You would isolate them and test the part that you're interested in. I recommend that you look into Inversion of Control as well as one of the many Mocking Frameworks (Moq, Rhino Mocks etc.)
You probably don't want to SKIP the external. Instead you want to isolate the external dependencies such as accessing external devices. There are many ways to do this
a. You can use a third part isolation framework such as Moq, or RhinoMock, etc
b. You can use Moles framework (since you are using VS2010) - replace a .NET method with a delegate
http://research.microsoft.com/en-us/projects/moles/
c. Paid isolation frameworks such as TypeMock.
d. Or simply hand written fake implementation which uses in interface and your test uses the Fake implementation.

Moq Assert an abstract method is called

I'm writing a unit test for my Abstract class using AutoFixture, this is a representation of what I'm trying to do:
public abstract class Base
{
public virtual void DoSomethingCool()
{
OnDoingSomethingCool();
}
protected abstract void OnDoingSomethingCool();
}
My unit test would look like this:
[TestMethod]
public void TestMethod1()
{
var fixture = new Fixture().Customize(new AutoMoqCustomization());
var sut = fixture.Create<Base>();
// How to assert that the OnDoingSomethingCool method was called
sut.Invoking(x => x.DoSomethingCool())
.ShouldNotThrow();
}
So how do I assert that the protected abstract method was actually called in the DoSomethingCool method??
If it were an object from an injected dependency, I would be able to setup a mock using Moq and assert that the method was called, but since the method is an abstract method inside my Subject Under Test, how do I assert the method was called?
There is a bunch that can be said about this:
It seems like you might be either testing too much, or giving too much control to other implementations.
(Too much control) Usually, if you want to force a method to be called from another method in your abstract class you do not make it public virtual. By doing this, you have given the future implementations the ability to change this behavior. In fact, if you remove the virtual, then you can get the test you want (see below). I did provide a way to keep the virtual, but again...not recommended. This is not recommended since your SUT is your mock...which doesn't feel right.
(Testing too much) You should only care about basic behavior, not implementation details, lest your tests become too brittle. I am assuming that there is more than just the call to the OnDoingSomethingCool method, otherwise you should just make that your main method. If the primary behavior is this call (and there is more than just this call), then I do cover that in my NotRecommended method below.
You should not test the abstract class directly. You should probably use what Roy Osherove calls the Abstract Test Class Pattern in The Art of Unit Testing. This makes it so that all implementations test your behavior. You can then pass in a dependency. If you would like that example or even a simplified example off the Abstract Test Class Pattern, let me know
/
using Moq.Protected;
...
public void NotRecommended_ProbablyTestingTooMuch_BrittleTestBelow
{
//If you MUST keep DoSomethingCool virtual
//var baseMock = new Mock<Base>{CallBase = true};
var baseMock = new Mock<Base>();
baseMock.Protected().Setup("OnDoingSomethingCool");
baseMock.Object.DoSomethingCool();
baseMock.Protected().Verify("OnDoingSomethingCool", Times.AtLeastOnce());
}

Rhino Mocks verify a private method is called from a public method

I have been trying to figure this one out, how do i test that a private method is called with rhino mocks with in the class that I am testing. So my class would be something like this.
Public class Foo
{
public bool DoSomething()
{
if(somevalue)
{
//DoSomething;
}
else
{
ReportFailure("Failure");
}
}
private void ReportFailure(string message)
{
//DoSomeStuff;
}
}
So my unit test is on class Foo and method DoSomething() I want to check and make sure that a certain message is passed to ReportFailure if somevalue is false, using rhino mocks.
There probably is a way to do this, but in most circumstances you don't want to do this. Your unit tests shouldn't depend on hidden implementations or code. Treat your classes as black boxes when you test them, where you only have access to changing the input and testing the output.
If you are testing private method execution, you are very likely diving too far into the implementation of a given class, and you're making it difficult to change your implementation down the road without breaking tests.
I agree with mjd79's answer, however if you're married to the idea of verifying that ReportFailure was called then you could change the protection level of the method to Internal, and set the InternalsVisibleTo attribute on your assembly so that it allows your unit tests to access it.
A better approach might be to mock whatever resource ReportFailure accesses, and verify that some public method on that mock is invoked.

Verifying a method was called

Using Moq, I have a very odd issue where the setup on a mock only seems to work if the method I am setting up is public. I don't know if this is a Moq bug or if I just have this wrong (newbie to Moq). Here is the test case:
public class TestClass
{
public string Say()
{
return Hello();
}
internal virtual string Hello()
{
return "";
}
}
[TestMethod]
public void Say_WhenPublic_CallsHello()
{
Mock<TestClass> mock = new Mock<TestClass>();
mock.Setup(x => x.Hello()).Returns("Hello World");
string result = mock.Object.Say();
mock.Verify(x => x.Hello(), Times.Exactly(1));
Assert.AreEqual("Hello World", result);
}
Which fails with this message:
Say_WhenPublic_CallsHello failed: Moq.MockException:
Invocation was not performed on the mock 1 times: x => x.Hello()
at Moq.Mock.ThrowVerifyException(IProxyCall expected, Expression expression, Times times)...
If I make the Hello method public like this, the test passes. What is the issue here?
public virtual string Hello()
{
return "";
}
Thanks in advance!
The test fails when Hello() is internal because Moq cannot provide an override of the method in this case. This means that the internal implementation of Hello() will run, rather than mock's version, causing the Verify() to fail.
Incidentally, what you are doing here makes no sense in the context of a unit test. A unit test should not care that Say() calls an internal Hello() method. This is implementation internal to your assembly and not a concern of consuming code.
I don't know enough about how this works underneath the covers to give you a technical answer as to exactly why that is the behaviour, but I think I can help with your confusion.
In your example you are calling a method Say(), and it is returning the expected text. Your expectation should not enforce a particular implementation of Say() ie that it calls an internal method called Hello() to return that string. This is why it does not pass the verify, and also why the string returned is "", ie the actual implementation of Hello() has been called.
By making the Hello method public it appears that this has enabled Moq to intercept the call to it, and use it's implementation instead. Therefore, in this case the test appears to pass. However, in this scenario you haven't really achieved anything useful, because your test says that when you call Say() the result is "Hello World" when in acutal fact the result is "".
I have rewritten your example to show how I would expect Moq to be used (not necessarily definitive, but hopefully clear.
public interface IHelloProvider
{
string Hello();
}
public class TestClass
{
private readonly IHelloProvider _provider;
public TestClass(IHelloProvider provider)
{
_provider = provider;
}
public string Say()
{
return _provider.Hello();
}
}
[TestMethod]
public void WhenSayCallsHelloProviderAndReturnsResult()
{
//Given
Mock<IHelloProvider> mock = new Mock<IHelloProvider>();
TestClass concrete = new TestClass(mock.Object);
//Expect
mock.Setup(x => x.Hello()).Returns("Hello World");
//When
string result = concrete.Say();
//Then
mock.Verify(x => x.Hello(), Times.Exactly(1));
Assert.AreEqual("Hello World", result);
}
In my example, I have introduced an interface to an IHelloProvider. You will notice that there is no implementation of IHelloProvider. This is at the heart of what we are trying to achieve by using a mocking solution.
We are trying to test a class (TestClass), which is dependant on something external (IHelloProvider). If you are using Test Driven Development then you probably haven't written an IHelloProvider yet, but you are aware that you will need one at some point. You want to get TestClass working first though, rather than get distracted. Or perhaps IHelloProvider uses a database, or a flat file, or is difficult to configure.
Even if you have a fully working IHelloProvider, you are still only trying to test the behaviour of TestClass, so using a concrete HelloProvider is likely to make your test more prone to failure, for instance if there is a change to the behaviour of HelloProvider, you don't want to have to change the tests of every class that uses it, you just want to change the HelloProvider tests.
Getting back to the code, we now have a class TestClass, which is dependant on an interface IHelloProvider, the implementation of which is provided at construction time (this is dependency injection).
The behaviour of Say() is that it calls the method Hello() on the IHelloProvider.
If you look back at the test, we have created an actual TestClass object, since we actually want to test the code that we have written. We have created a Mock IHelloProvider, and said that we expect it to have it's Hello() method called, and when it does to return the string "Hello World".
We then call Say(), and verify the results as before.
The important thing to realise is that we are not interested in the behaviour of the IHelloProvider, and so we can mock it to make testing easier. We are interested in the behaviour of TestClass, so we have created an actual TestClass not a Mock, so that we can test it's actual behaviour.
I hope this has helped to clarify what is going on.
Moq doesn't do partial mocking and can only mock public virtual methods or interfaces. When you create a Mock you are creating a completely new T and removing all implementation of any public virtual methods.
My suggestion would be to concentrate on testing the public surface area of your objects and not their internals. Your internals will get coverage. Just make sure you have a clear idea of what your target class is and don't mock that (in most cases).
Partial mocking is only useful when you want to test the functionality of an abstract class with mocked implementations of abstract methods. If you aren't doing this, you are likely not going to see much benefit from doing a partial mock.
If this is not an abstract class, you will want to focus more on the approach Modan suggests, which is to say that you should mock dependencies rather than your target class itself. All of this boils down to the rule don't mock what you are testing.

Categories

Resources