I have the following classes:
public class HelperClass
{
HandleFunction<T>(Func<T> func)
{
// Custom logic here
func.Invoke();
// Custom logic here
}
// The class i want to test
public class MainClass
{
public readonly HelperClass _helper;
// Ctor
MainClass(HelperClass helper)
{
_helper = helper;
}
public void Foo()
{
// Use the handle method
_helper.HandleFunction(() =>
{
// Foo logic here:
Action1();
Action2(); //etc..
}
}
}
I want to test MainClass only. I a using RhinoMocks to mock HelperClass in my tests.
The problem is, while I am not interested in testing the HandleFunction() method I am interested in checking Action1, Action2 and other actions that were sent to HandleFunction() when called..
How can I mock the HandleFunction() method and while avoiding it's inner logic, invoke the code that was sent to it as a parameter?
Because your unit under test most probably requires the delegate to be called before proceeding, you need to call it from the mock. There is still a difference between calling the real implementation of the helper class and the mock implementation. The mock does not include this "custom logic". (If you need that, don't mock it!)
IHelperClass helperMock = MockRepository.GenerateMock<IHelperClass>();
helperMock
.Stub(x => x.HandleFunction<int>())
.WhenCalled(call =>
{
var handler = (Func<int>)call.Argument[0];
handler.Invoke();
});
// create unit under test, inject mock
unitUnderTest.Foo();
In addition to Stefan's answer I'd like to show quite another way to define stub which invokes passed argument:
handler
.Stub(h => h.HandleFunction(Arg<Func<int>>.Is.Anything))
.Do((Action<Func<int>>)(func => func()));
Please read more about Do() handler here and here.
Related
I have a preexisting Interface...
public interface ISomeInterface
{
void SomeMethod();
}
and I've extended this intreface using a mixin...
public static class SomeInterfaceExtensions
{
public static void AnotherMethod(this ISomeInterface someInterface)
{
// Implementation here
}
}
I have a class thats calling this which I want to test...
public class Caller
{
private readonly ISomeInterface someInterface;
public Caller(ISomeInterface someInterface)
{
this.someInterface = someInterface;
}
public void Main()
{
someInterface.AnotherMethod();
}
}
and a test where I'd like to mock the interface and verify the call to the extension method...
[Test]
public void Main_BasicCall_CallsAnotherMethod()
{
// Arrange
var someInterfaceMock = new Mock<ISomeInterface>();
someInterfaceMock.Setup(x => x.AnotherMethod()).Verifiable();
var caller = new Caller(someInterfaceMock.Object);
// Act
caller.Main();
// Assert
someInterfaceMock.Verify();
}
Running this test however generates an exception...
System.ArgumentException: Invalid setup on a non-member method:
x => x.AnotherMethod()
My question is, is there a nice way to mock out the mixin call?
I have used a Wrapper to get around this problem. Create a wrapper object and pass your mocked method.
See Mocking Static Methods for Unit Testing by Paul Irwin, it has nice examples.
You can't "directly" mock static method (hence extension method) with mocking framework. You can try Moles (http://research.microsoft.com/en-us/projects/pex/downloads.aspx), a free tool from Microsoft that implements a different approach.
Here is the description of the tool:
Moles is a lightweight framework for test stubs and detours in .NET that is based on delegates.
Moles may be used to detour any .NET method, including non-virtual/static methods in sealed types.
You can use Moles with any testing framework (it's independent about that).
I found that I had to discover the inside of the extension method I was trying to mock the input for, and mock what was going on inside the extension.
I viewed using an extension as adding code directly to your method. This meant I needed to mock what happens inside the extension rather than the extension itself.
I like to use the wrapper (adapter pattern) when I am wrapping the object itself. I'm not sure I'd use that for wrapping an extension method, which is not part of the object.
I use an internal Lazy Injectable Property of either type Action, Func, Predicate, or delegate and allow for injecting (swapping out) the method during a unit test.
internal Func<IMyObject, string, object> DoWorkMethod
{
[ExcludeFromCodeCoverage]
get { return _DoWorkMethod ?? (_DoWorkMethod = (obj, val) => { return obj.DoWork(val); }); }
set { _DoWorkMethod = value; }
} private Func<IMyObject, string, object> _DoWorkMethod;
Then you call the Func instead of the actual method.
public object SomeFunction()
{
var val = "doesn't matter for this example";
return DoWorkMethod.Invoke(MyObjectProperty, val);
}
For a more complete example, check out http://www.rhyous.com/2016/08/11/unit-testing-calls-to-complex-extension-methods/
If you just want to make sure that the extension method was invoked, and you aren't trying to setup a return value, then you can check the Invocations property on the mocked object.
Like this:
var invocationsCount = mockedObject.Invocations.Count;
invocationsCount.Should().BeGreaterThan(0);
Reason why it is not possible to mock an extension method is already given in good answers. I am just trying to give another possible solution with this answer: Extract a protected, virtual method with the call to the extension method and create a setup for this method in the test class/method by using a proxy.
public class Foo
{
public void Method()
=> CallToStaticMethod();
protected virtual void CallToStaticMethod()
=> StaticClass.StaticMethod();
}
and test
[TestMethod]
public void MyTestMethod()
{
var expected = new Exception("container exception");
var proxy = new Mock<Foo>();
proxy.Protected().Setup("CallToStaticMethod").Throws(expected);
var actual = Assert.ThrowsException<Exception>(() => proxy.Object.Foo());
Assert.AreEqual(expected, actual);
}
In my case extension method is a method around some public method of my class. So I checked call of that internal method. That approach is similar to Alvis answer (above).
So if you are using Moq, and want to mock the result of an Extension method, then you can use SetupReturnsDefault<ReturnTypeOfExtensionMethod>(new ConcreteInstanceToReturn()) on the instance of the mock class that has the extension method you are trying to mock.
It is not perfect, but for unit testing purposes it works well.
public class Controller
{
public GetSomeData()
{
retun someData;
}
public dosomthing(Some someObj)
{
var getData = GetSomeData();
return service.DosomethingElse(getData);
}
}
I have mocked service.DosomethingElse(getData);.
I've also mocked GetSomeData(); but it returns "" (blank value) I want to return with "myData".
I've written a TestMethod like this:
string someData ="myData";
var mockData = new Mock<Controller>();
mockData.Setup(x => x.GetSomeData()).Returns(someData);
var mockDa = new Mock<Service>();
mockDa.Setup(x => x.DosomethingElse(getData)).Returns(response);
Controller cObj= new Controller(mockDa.Object);
var actual = cObj.dosomthing(Some someObj);
Assert.AreEqual("expected",actual);
Please suggest how to mock GetSomeData() method of the same class.
You can't do that. You can't mock the GetSomeData for the controller you are testing. You can only mock the dependencies you inject to the class.
Think about it this way:
A mock is an object with specific behavior, mocking a real class object
A class object has the proper behavior
You can't have a hybrid object, a little bit of mock and a little bit of class.
By the way, even if you could, you shouldn't. When you are testing a method, you also test the other methods of the same class that are used within. This is also the way you are testing the private functions of a class.
interface ITest
{
void Run();
}
class Test : ITest
{
void ITest.Run() => Run();
public int Run()
{
//...
}
}
Hello, how to verify that ITest.Run() execute "Run" of Test?
You could test this using a mocking framework like Moq:
public interface ITest
{
void Run();
}
public class Test : ITest
{
void ITest.Run() => Run();
public virtual int Run()
{
return 1; // doesn’t matter, will be replaced by our mock
}
}
The test would then look like this:
// arrange
Mock<Test> mock = new Mock<Test>();
mock.CallBase = true;
mock.Setup(t => t.Run()).Returns(1);
// act
ITest test = mock.Object;
test.Run();
// assert
mock.Verify(t => t.Run(), Times.Once());
This correctly throws when ITest.Run does not call the Run of Test. However, as you can see, doing this requires the Run method to be virtual so that the mock can overwrite it with its own implementation. This might not be desireable.
And ultimately, that test doesn’t does not make any sense. When you unit test something, you want to unit test the behavior, not the implementation. So it shouldn’t matter to you whether the explicit implementation ITest.Run calls another method on the object or not. You should only care about that the behavior of calling that method is correct.
To test interface is the easiest task!
You can simply do it with Typemock Isolator (no virtual methods needed), take a look:
[TestMethod, Isolated]
public void TestRun()
{
//Arrange
var fake = Isolate.Fake.Instance<ITest>();
Isolate.WhenCalled(() => fake.Run()).CallOriginal();
//Act
fake.Run();
//Assert
Isolate.Verify.WasCalledWithAnyArguments(() => fake.Run());
}
You are mocking the interface, then setting the behavior to Run() method (it's optional), and after all you can verify the call was made.
Hope it helps!
It does not make sense to verify that Run is called unless your interface is used in another class. (not the class implementing it). So if you have a second class USING your ITest-interface, then it makes sense to verify that Run is called as you have done
I'm trying to test that a method is called between 3 and 4 times:
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Rhino.Mocks;
using StructureMap.AutoMocking;
namespace AutoMockPlayground
{
[TestClass]
public class SomeTests
{
[TestMethod]
public void Bara_ShouldBeCalledThreeOrFourTimes()
{
var autoMocker = new RhinoAutoMocker<Foo>(MockMode.AAA);
var barMock = autoMocker.Get<IBar>();
// Bara() should not be called more than four times
barMock.Stub(bar => bar.Bara()).Repeat.Times(3, 4);
autoMocker.ClassUnderTest.DoSomeThing();
barMock.VerifyAllExpectations();
}
}
public interface IBar
{
void Bara();
}
public class Foo
{
private readonly IBar _bar;
public Foo(IBar bar)
{
_bar = bar;
}
public void DoSomeThing()
{
_bar.Bara();
_bar.Bara();
_bar.Bara();
_bar.Bara();
_bar.Bara();
}
}
}
I'm using the Repeat.Times(int min, int max), but the max argument does not seem to have any effect.
This test passes although Bara() is called 5 times.
How can I express in my test that Bara() should be called between 3 and 4 times?
Stub by definition will not check the expectation, see also this.
However, you can verify the expectation simply by calling AssertWasCalled
You can modify your code as follows:
var autoMocker = new RhinoAutoMocker<Foo>(MockMode.AAA);
var barMock = autoMocker.Get<IBar>();
autoMocker.ClassUnderTest.DoSomeThing();
// Bara() should not be called more than four times
barMock.AssertWasCalled(bar => bar.Bara(),
options => options.IgnoreArguments().Repeat.Times(3,4));
I'm not familiar with RhinoAutoMocker, but it looks like barMock is being used as a stub object rather than a mock object.
If it's a stub (i.e. by using .Stub()) then calling VerifyAllExpectations() will have not effect. Instead, it needs to be a mock object, where calling VerifyAllExpectations() should work.
For example, here's how I use a mock in my tests.
var mockObject = MockRepository.GenerateMock<IFoo>();
mockObject.Expect(o => o.CallSomething().Repeat.Times(1);
mockObject.VerifyAllExpecttions();
So instead of
barMock.Stub(bar => bar.Bara()).Repeat.Times(3, 4);
can you do
barMock.Expect(bar => bar.Bara()).Repeat.Times(3, 4);
EDIT:
Just to expand:
Stub
A stub is an object which you do not intend to assert anything against. You use a stub to plug in default values for method return values, or to stub out calls to void methods.
Calling .Verfiyxxxx on a stub object will have no effect, since by definition a stub does not keep track of how that object was interacted with, it simply knows "When method x() is called, do this other action instead".
Mock
If you wish to assert an interaction with an object e.g. that a method was called 4 times, or a method was called with a particular set of arguments, then you need a mock object. Using a mock entails calling Expect (this depends on the mocking framework you're using, but it's usually Expect)
I have a preexisting Interface...
public interface ISomeInterface
{
void SomeMethod();
}
and I've extended this intreface using a mixin...
public static class SomeInterfaceExtensions
{
public static void AnotherMethod(this ISomeInterface someInterface)
{
// Implementation here
}
}
I have a class thats calling this which I want to test...
public class Caller
{
private readonly ISomeInterface someInterface;
public Caller(ISomeInterface someInterface)
{
this.someInterface = someInterface;
}
public void Main()
{
someInterface.AnotherMethod();
}
}
and a test where I'd like to mock the interface and verify the call to the extension method...
[Test]
public void Main_BasicCall_CallsAnotherMethod()
{
// Arrange
var someInterfaceMock = new Mock<ISomeInterface>();
someInterfaceMock.Setup(x => x.AnotherMethod()).Verifiable();
var caller = new Caller(someInterfaceMock.Object);
// Act
caller.Main();
// Assert
someInterfaceMock.Verify();
}
Running this test however generates an exception...
System.ArgumentException: Invalid setup on a non-member method:
x => x.AnotherMethod()
My question is, is there a nice way to mock out the mixin call?
I have used a Wrapper to get around this problem. Create a wrapper object and pass your mocked method.
See Mocking Static Methods for Unit Testing by Paul Irwin, it has nice examples.
You can't "directly" mock static method (hence extension method) with mocking framework. You can try Moles (http://research.microsoft.com/en-us/projects/pex/downloads.aspx), a free tool from Microsoft that implements a different approach.
Here is the description of the tool:
Moles is a lightweight framework for test stubs and detours in .NET that is based on delegates.
Moles may be used to detour any .NET method, including non-virtual/static methods in sealed types.
You can use Moles with any testing framework (it's independent about that).
I found that I had to discover the inside of the extension method I was trying to mock the input for, and mock what was going on inside the extension.
I viewed using an extension as adding code directly to your method. This meant I needed to mock what happens inside the extension rather than the extension itself.
If you just want to make sure that the extension method was invoked, and you aren't trying to setup a return value, then you can check the Invocations property on the mocked object.
Like this:
var invocationsCount = mockedObject.Invocations.Count;
invocationsCount.Should().BeGreaterThan(0);
I like to use the wrapper (adapter pattern) when I am wrapping the object itself. I'm not sure I'd use that for wrapping an extension method, which is not part of the object.
I use an internal Lazy Injectable Property of either type Action, Func, Predicate, or delegate and allow for injecting (swapping out) the method during a unit test.
internal Func<IMyObject, string, object> DoWorkMethod
{
[ExcludeFromCodeCoverage]
get { return _DoWorkMethod ?? (_DoWorkMethod = (obj, val) => { return obj.DoWork(val); }); }
set { _DoWorkMethod = value; }
} private Func<IMyObject, string, object> _DoWorkMethod;
Then you call the Func instead of the actual method.
public object SomeFunction()
{
var val = "doesn't matter for this example";
return DoWorkMethod.Invoke(MyObjectProperty, val);
}
For a more complete example, check out http://www.rhyous.com/2016/08/11/unit-testing-calls-to-complex-extension-methods/
Reason why it is not possible to mock an extension method is already given in good answers. I am just trying to give another possible solution with this answer: Extract a protected, virtual method with the call to the extension method and create a setup for this method in the test class/method by using a proxy.
public class Foo
{
public void Method()
=> CallToStaticMethod();
protected virtual void CallToStaticMethod()
=> StaticClass.StaticMethod();
}
and test
[TestMethod]
public void MyTestMethod()
{
var expected = new Exception("container exception");
var proxy = new Mock<Foo>();
proxy.Protected().Setup("CallToStaticMethod").Throws(expected);
var actual = Assert.ThrowsException<Exception>(() => proxy.Object.Foo());
Assert.AreEqual(expected, actual);
}
In my case extension method is a method around some public method of my class. So I checked call of that internal method. That approach is similar to Alvis answer (above).
So if you are using Moq, and want to mock the result of an Extension method, then you can use SetupReturnsDefault<ReturnTypeOfExtensionMethod>(new ConcreteInstanceToReturn()) on the instance of the mock class that has the extension method you are trying to mock.
It is not perfect, but for unit testing purposes it works well.