Verifying generic method called using Moq - c#

I'm having trouble verifying that mock of IInterface.SomeMethod<T>(T arg) was called using Moq.Mock.Verify.
I'm can verify that method was called on a "Standard" interface either using It.IsAny<IGenericInterface>() or It.IsAny<ConcreteImplementationOfIGenericInterface>(), and I have no troubles verifying a generic method call using It.IsAny<ConcreteImplementationOfIGenericInterface>(), but I can't verify a generic method was called using It.IsAny<IGenericInterface>() - it always says that the method was not called and the unit test fails.
Here is my unit test:
public void TestMethod1()
{
var mockInterface = new Mock<IServiceInterface>();
var classUnderTest = new ClassUnderTest(mockInterface.Object);
classUnderTest.Run();
// next three lines are fine and pass the unit tests
mockInterface.Verify(serviceInterface => serviceInterface.NotGenericMethod(It.IsAny<ConcreteSpecificCommand>()), Times.Once());
mockInterface.Verify(serviceInterface => serviceInterface.NotGenericMethod(It.IsAny<ISpecificCommand>()), Times.Once());
mockInterface.Verify(serviceInterface => serviceInterface.GenericMethod(It.IsAny<ConcreteSpecificCommand>()), Times.Once());
// this line breaks: "Expected invocation on the mock once, but was 0 times"
mockInterface.Verify(serviceInterface => serviceInterface.GenericMethod(It.IsAny<ISpecificCommand>()), Times.Once());
}
Here is my class under test:
public class ClassUnderTest
{
private IServiceInterface _service;
public ClassUnderTest(IServiceInterface service)
{
_service = service;
}
public void Run()
{
var command = new ConcreteSpecificCommand();
_service.GenericMethod(command);
_service.NotGenericMethod(command);
}
}
Here is my IServiceInterface:
public interface IServiceInterface
{
void NotGenericMethod(ISpecificCommand command);
void GenericMethod<T>(T command);
}
And here is my interface/class inheritance hierarchy:
public interface ISpecificCommand
{
}
public class ConcreteSpecificCommand : ISpecificCommand
{
}

It is a known issue in the Moq 4.0.10827 which is a current release version. See this discussion at GitHub https://github.com/Moq/moq4/pull/25. I have downloaded its dev branch, compiled and referenced it and now your test passes.

I'm going to wing it. Since GenericMethod<T> requires that a T argument be provided, would it be possible to do:
mockInterface.Verify(serviceInterface => serviceInterface.GenericMethod(It.Is<object>(x=> typeof(ISpecificCommand).IsAssignableFrom(x.GetType()))), Times.Once());

Related

Moq.MockException: Expected invocation on the mock exactly 1 times, but was 0 times: x => x.Init()

I have this method which verify if a method is called. I am using xUnit and MOQ in C#.
[Fact]
public void VerifyIfInitCalled()
{
// Arrange
var mock = new Mock<ICal>();
var cal = new Cal(mock.Object);
// Act
cal.Init();
// Assert
mock.Verify(x => x.Init(), Times.Exactly(1));
}
and for my Cal class
public class Cal : ICal
{
private ICal _cal;
public Cal(ICal cal)
{
_cal = cal;
}
public void Init()
{
Console.WriteLine("Init called"); ;
}
}
But, I run the unit test, it fails with error Moq.MockException :
Expected invocation on the mock exactly 1 times, but was 0 times: x => x.Init() although I have called the Init() method.
Your need to modify your Init() to get your assert right
public void Init()
{
_cal.Init();
Console.WriteLine("Init called"); ;
}
and your interface ICal need to have an Init() member.
But clearly you have a conception problem you are implementing ICal and passing it into the class constructor !!.
UPDATE
A unit test is specific to an implementation so your test method need to test the Cal class.
If your class call an other service and you need to mock and setup a method call to get specific result you will use moq

validate MOQ unit test method return value

I have the below class and test class written using Moq:
public class Mytest : testin
{
public int getId(int id)
{
int s = 2;
return s;
}
}
test class:
private Mock<testin> _mock;
[TestInitialize]
public void Setup()
{
_mock = new Mock<testin>();
}
[TestMethod]
public void returngetId()
{
// Build up our mock object
_mock.Setup(x => x.getId(It.IsAny<int>())).Returns(1)
}
I'm returning 2 from the function and in unit test cases checking for the value 1. As per my understanding the test cases should fail. But im getting success message. How i can validate the return value is exactly what im expecting? I want to fail the test if it returning other than 1.
Your current setup will skip the method's execution, and instead "blindly" return 1. You should not mock the method if you wish it to be executed. If you remove the setup line, your test cases will indeed fail. In general, you should only mock a method if you need it to NOT be executed.
To clarify:
The line _mock.Setup(x => x.getId(It.IsAny<int>())).Returns(1) configures your mock object so that whenever you call the getId method, instead of executing it, the value 1 will always be returned. So, the following test would pass:
[TestMethod]
public void returngetId_Always1()
{
// ... Build up our mock object
_mock.Setup(x => x.getId(It.IsAny<int>())).Returns(1);
Assert.AreEqual(1, _mock.Object.getId("foo"));
Assert.AreEqual(1, _mock.Object.getId("bar"));
}
In order to get the actual implementation of the method to be invoked from within the mock, you have to mock the class, not the interface, with the following configuration:
[TestMethod]
public void returngetId_CallBase()
{
var mock = new Mock<MyTest>() { CallBase = true };
// add other method setups here. DO NOT setup the getId() method.
Assert.AreEqual(2, _mock.Object.getId("foo"));
Assert.AreEqual(2, _mock.Object.getId("bar"));
}
This will allow the mock to defer to the base implementation for any methods for which a mocking setup has not been provided.

How to test Interface Method

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

How to fake an action<> with FakeItEasy

I'm working with the FakeItEasy library to create fakes for my unit tests.
I have a ClassUnderTest on which I want to test the method MethodToTest(Data dataObject). This method is calling a method of an interface which I want to fake:
public interface IFoo
{
void Execute(Action<IDataAccess> action);
}
public class ClassUnderTest
{
private IFoo _foo;
public ClassUnderTest(IFoo foo)
{
_foo = foo;
}
public void MethodToTest(Data dataObject)
{
_foo.Execute(dataAccess => dataAccess.Update(dataObject));
}
}
public interface IDataAccess
{
void Update(Data data);
}
public class Data
{
public int Property { get; set; }
}
In my unit tests I want to check if the test method calls the interface correctly (with the correct property value):
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
var foo = A.Fake<IFoo>(x => x.Strict());
A.CallTo(() => foo.Execute(dataAccess => dataAccess.Update(A<Data>.That.Matches(d => d.Property == 20))));
var cut = new ClassUnderTest(foo);
cut.MethodToTest(new Data { Property = 20 });
}
}
But something is configured wrong in this test. I get the exception:
Test method TestProject1.UnitTest1.TestMethod1 threw exception:
FakeItEasy.ExpectationException: Call to non configured method "Execute" of strict fake.
Does somebody have an idea of how I have to configure the CallTo() statement correctly?
The updated example really helps, #rhe1980.
First some notes about the test you supplied:
the A.CallTo method doesn't do anything - it's not setting up behaviour (with a .Invokes or a .Returns or even a .DoesNothing) or verifying that the method has been called (for example with .MustHaveHappened).
Comparing Actions appears to be tough. I did find some advice over at Compare Delegates Action<T>, but if it were me, I'd take a slightly different tack.
Instead of attempting to compare the Action delegate to a reference model, I figured I could emulate this by capturing the action supplied to Execute and then running it on an IDataAccess and see what the action does. Fortunately, we have FakeItEasy to help with that!
I had success with this test:
[TestMethod]
public void TestMethod1()
{
// Arrange
var foo = A.Fake<IFoo>(x => x.Strict());
var fakeDataAccess = A.Fake<IDataAccess>();
A.CallTo(() => foo.Execute(A<Action<IDataAccess>>.Ignored))
.Invokes((Action<IDataAccess> action)=>action(fakeDataAccess));
var cut = new ClassUnderTest(foo);
// Act
cut.MethodToTest(new Data { Property = 20 });
// Assert
A.CallTo(() => fakeDataAccess.Update(A<Data>.That.Matches(d => d.Property == 20)))
.MustHaveHappened();
}
I hope it helps.
If I understood your intentions correctly, you need to use something as follows:
A.CallTo(() => foo.Execute(A<Action<IDataAccess>>.Ignored).MustHaveHappened();

Verify method has been called with IEnumerable containing 'x' elements with Moq

I have a repository with an Add method that takes an IEnumerable as parameter:
public void Add<T>(T item) where T : class, new(){}
In a unittest I want to verify that this method is called with an IEnumerable that contains exactly the same amount of elements as another IEnumerable
[Test]
public void InvoicesAreGeneratedForAllStudents()
{
var students = StudentStub.GetStudents();
session.Setup(x => x.All<Student>()).Returns(students.AsQueryable());
service.GenerateInvoices(Payments.Jaar, DateTime.Now);
session.Verify(x => x.Add(It.Is<IEnumerable<Invoice>>(
invoices => invoices.Count() == students.Count())));
}
Result of the unit test:
Moq.MockException :
Expected invocation on the mock at least once, but was never performed:
x => x.Add<Invoice>(It.Is<IEnumerable`1>(i => i.Count<Invoice>() == 10))
No setups configured.
What am I doing wrong?
From your code example you haven't set up the x => x.Add on the Moq
session.Setup(x => x.Add(It.IsAny<IEnumerable>());
Unless the Setup for x.All is meant to be x.Add? If so, you need to match the Verify and Setup exactly - a good way to do that is to extract it to a common method that returns an Expression.
EDIT: Added a sample, I have changed the signature of Add as I can't see how you could pass a collection otherwise.
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
Mock<Boo> moqBoo = new Mock<Boo>();
moqBoo.Setup(IEnumerableHasExpectedNumberOfElements(10));
// ACT
moqBoo.Verify(IEnumerableHasExpectedNumberOfElements(10));
}
private static Expression<Action<Boo>> IEnumerableHasExpectedNumberOfElements(int expectedNumberOfElements)
{
return b => b.Add(It.Is<IEnumerable<Invoice>>(ie => ie.Count() == expectedNumberOfElements));
}
}
public class Boo
{
public void Add<T>(IEnumerable<T> item) where T : class, new()
{
}
}
public class Invoice
{
}
Also, a good way to debug these things is to set your Mock up with MockBehavior.Strict and then you'll be informed by the invoked code what you need to configure.

Categories