I have a statement similar to
var res = _serviceA.MethodA(() => _serviceB.MethodB(new objectA(){ Id = 10 })
which is being called twice in the method and also the response changes based on the value of Id
, hence I need to setup the response such that a different object is returned based on the the Id
value.
Current mock:
_serviceAMock.Setup(x => x.MethodA(It.IsAny<Func<ResponseObject>>())).Return(responseOfTypeResponseObject);
Is it possible to achieve this using moq? if yes how? I was able to mock MethodA
and get the response but I couldn't figure out how to mock it such that the result varies based on the Id
value.
Mocking Class:
public class ClassToTest
{
private readonly IServiceA<int> _serviceA;
private readonly IServiceB _serviceB;
public ClassToTest(IServiceA<int> serviceA, IServiceB serviceB)
{
_serviceA = serviceA;
_serviceB = serviceB;
}
public void MethodToTest()
{
var res = _serviceA.MethodA(() => _serviceB.MethodB(new ObjectA() { Id = 10 }));
}
}
Supporting objects:
public class ObjectA
{
public int Id { get; set; }
}
public interface IServiceB
{
int MethodB(ObjectA objectA);
}
public interface IServiceA<T>
{
T MethodA(Func<T> handler);
}
That worked for me:
using FluentAssertions;
using Moq;
namespace MockDifferentResult;
public class Tests
{
[Test]
public void Test1()
{
// Arrange
var serviceBMock = new Mock<IServiceB>();
serviceBMock
.Setup(service => service.MethodB(It.Is<ObjectA>(a => a.Id == 10)))
.Returns(1);
serviceBMock
.Setup(service => service.MethodB(It.Is<ObjectA>(a => a.Id == 20)))
.Returns(2);
var serviceAMock = new Mock<IServiceA<int>>();
serviceAMock
.Setup(service => service.MethodA(It.IsAny<Func<int>>()))
.Returns<Func<int>>(handler => handler());
var testee = new ClassToTest(serviceAMock.Object, serviceBMock.Object);
// Act
testee.MethodToTest();
// Assert
testee.Res1.Should().Be(1);
testee.Res2.Should().Be(2);
}
}
public class ClassToTest
{
private readonly IServiceA<int> _serviceA;
private readonly IServiceB _serviceB;
public int Res1 { get; private set; }
public int Res2 { get; private set; }
public ClassToTest(IServiceA<int> serviceA, IServiceB serviceB)
{
_serviceA = serviceA;
_serviceB = serviceB;
}
public void MethodToTest()
{
Res1 = _serviceA.MethodA(() => _serviceB.MethodB(new ObjectA { Id = 10 }));
Res2 = _serviceA.MethodA(() => _serviceB.MethodB(new ObjectA { Id = 20 }));
}
}
public class ObjectA
{
public int Id { get; set; }
}
public interface IServiceB
{
int MethodB(ObjectA objectA);
}
public interface IServiceA<T>
{
T MethodA(Func<T> handler);
}
Please give it a try and see if it suffices your needs.