Moq override previous setup? - c#

Hi I am trying to set an mock of a class's method with two possible input. When i check output only the last set up return expected output. The first one did not. Any help is much appreciated.
[Test]
public void ClimbOnceTwoNeighbour_Sample()
{
stateConverter = new Mock<StateConverter>();
solution = new Mock<Solution>();
state = new Mock<State>();
var neightbourSolution1 = new Mock<Solution>();
var neighbourState1 = new Mock<State>();
var neightbourSolution2 = new Mock<Solution>();
var neighbourState2 = new Mock<State>();
stateConverter.Setup(x => x.FromSolution(neightbourSolution1.Object, It.IsAny<State>())).Returns(neighbourState1.Object);
stateConverter.Setup(x => x.FromSolution(neightbourSolution2.Object, It.IsAny<State>())).Returns(neighbourState2.Object);
var state1 = stateConverter.Object.FromSolution(neightbourSolution1.Object, state.Object);//return null ????
var state2 = stateConverter.Object.FromSolution(neightbourSolution2.Object, state.Object);//return neighbourState2.Object)
Assert.AreEqual(neighbourState2.Object, state2);//pass test here
Assert.AreEqual(neighbourState1.Object, state1);//fail here due to null is returned from previous statement
}

I have copied your code snippet and created empty classes to make it compile. It works as expected. Try it please and let me know what was the result.
Here is the code:
using Moq;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
var stateConverter = new Mock<StateConverter>();
var solution = new Mock<Solution>();
var state = new Mock<State>();
var neightbourSolution1 = new Mock<Solution>();
var neighbourState1 = new Mock<State>();
var neightbourSolution2 = new Mock<Solution>();
var neighbourState2 = new Mock<State>();
stateConverter.Setup(x => x.FromSolution(neightbourSolution1.Object, It.IsAny<State>())).Returns(neighbourState1.Object);
stateConverter.Setup(x => x.FromSolution(neightbourSolution2.Object, It.IsAny<State>())).Returns(neighbourState2.Object);
var state1 = stateConverter.Object.FromSolution(neightbourSolution1.Object, state.Object);
var state2 = stateConverter.Object.FromSolution(neightbourSolution2.Object, state.Object);
}
}
public class State{}
public class Solution{}
public abstract class StateConverter
{
public abstract State FromSolution(Solution p0, State isAny);
}
}

One of the habits I've got into with Moq is to use the full It.Is(o => o == object) syntax to avoid any issues when the setup could be ambiguous or implicit. It could be that Moq is simply taking the object in the setup and overriding any others it already had there.
stateConverter.Setup(x => x.FromSolution(neightbourSolution1.Object, It.IsAny<State>())).Returns(neighbourState1.Object);
stateConverter.Setup(x => x.FromSolution(neightbourSolution2.Object, It.IsAny<State>())).Returns(neighbourState2.Object);
Would then look like
stateConverter.Setup(x => x.FromSolution(It.Is<Solution>(solution => solution == neightbourSolution1.Object), It.IsAny<State>())).Returns(neighbourState1.Object);
stateConverter.Setup(x => x.FromSolution(It.Is<Solution>(solution => solution == neightbourSolution2.Object), It.IsAny<State>())).Returns(neighbourState2.Object);
I'm not too sure if this would solve your issue as the implicitness is pretty damn clear. :/

Have you tried something like this?
[Test]
public void ClimbOnceTwoNeighbour_Sample()
{
stateConverter = new Mock<StateConverter>();
solution = new Mock<Solution>();
state = new Mock<State>();
var neightbourSolution1 = new Mock<Solution>();
var neighbourState1 = new Mock<State>();
var neightbourSolution2 = new Mock<Solution>();
var neighbourState2 = new Mock<State>();
stateConverter.Setup(x => x.FromSolution(neightbourSolution1.Object, It.IsAny<State>())).Returns(neighbourState1.Object);
var state1 = stateConverter.Object.FromSolution(neightbourSolution1.Object, state.Object);//return null ????
stateConverter.Setup(x => x.FromSolution(neightbourSolution2.Object, It.IsAny<State>())).Returns(neighbourState2.Object);
var state2 = stateConverter.Object.FromSolution(neightbourSolution2.Object, state.Object);//return neighbourState2.Object)
Assert.AreEqual(neighbourState2.Object, state2);//pass test here
Assert.AreEqual(neighbourState1.Object, state1);//fail here due to null is returned from previous statement
}
I think that this way, when you assing to your state1 the result of the first return, you can use Setup again and add the result to state2 ;)

Related

Mock.Verify() failed - This setup was not matched?

I have the following test code.
var test = "Test";
var command = new MyCommand { V = test };
var mock = new Mock<IRepository>(); // IRepository has the method of Save()
var p = new P(test);
mock.Setup(x => x.Save(p)).Verifiable();
var sut = new C(mock.Object);
var result = await sut.M(command);
mock.Verify();
The test should pass. However, it failed with the error of,
Message:
Moq.MockException : Mock:
This mock failed verification due to the following:
IRepository x => x.Save(P):
This setup was not matched.
Stack Trace:
Mock.Verify()
sut.M() will convert a string X to type P with value of P(X).
It seems to me that you want to verify that the Save method from your mock is called with a specific value, and not just a type.
I have tried something like the following and believe it should work. I have modified your example.
var test = "Test";
var command = new MyCommand { V = test };
var mock = new Mock<IRepository>(); // IRepository has the method of Save()
var p = new P(test);
mock.Setup(x => x.Save(It.IsAny<P>());
var sut = new C(mock.Object);
var result = await sut.M(command);
mock.Verify(x => x.Save(It.Is<P>(v => v.Value.Equals(p.Value))), Times.AtLeastOnce);
This tests that the values of the specific property are equal.
I Tested this with the following test:
var test = "Test";
var mock = new Mock<ITestRepository>(); // ITestRepository has the method of Save()
var p = new P(test);
mock.Setup(x => x.Save(It.IsAny<P>()));
mock.Object.Save(new P(test));
mock.Verify(x => x.Save(It.Is<P>(v => v.Value.Equals(p.Value))), Times.AtLeastOnce);

Unit Testing xUnit Asserting 2 Collections with Moq Interface

Good day everyone,
I'm new in xunit and even in unit testing. I have a code here and I'm trying to assert two collection of list. But I have no idea how to assert and pass this test. Here's my code
[Theory]
[InlineData(1)]
public void GetAllStudents_Exempt1(int number)
{
// arrange
var studentRepo = new Mock<IStudentRepository>();
var listOfStudents = new List<Student> { new Student { StudentId = 1, Firstname = "Firstname1", Lastname = "Firstname1" },
new Student{StudentId=2, Firstname="Firstname2",Lastname="Lastname2"} };
var getAllStudentDetailsExempt1 = studentRepo.Setup(s => s.GetStudents()).Returns(listOfStudents.Where(x => x.StudentId != number));
var studentService = new StudentService(studentRepo.Object);
// act
var getStudentsDetails = studentService.ListOfStudentsExempt1(1);
// assert
// I don't have any idea how to assert
}
First a few notes:
var getAllStudentDetailsExempt1 = studentRepo
.Setup(s => s.GetStudents())
.Returns(listOfStudents.Where(x => x.StudentId != number));
you don't need var getAllStudentDetailsExempt1, you can just setup your repo-mock...
studentRepo
.Setup(s => s.GetStudents())
.Returns(listOfStudents.Where(x => x.StudentId != number));
You probably want to change:
// act
var getStudentsDetails = studentService.ListOfStudentsExempt1(1);
to use the number variable...
// act
var getStudentsDetails = studentService.ListOfStudentsExempt1(number);
So then you can assert by checking some properties:
Assert.Equals(1, getStudentsDetails.Count);
Assert.Equals("FirstName1", getStudentsDetails.First().Firstname);
etc. etc.
Give it a shot!

Count files from request with Moq

The SetupGet for Form work, but the Count not work. How to resolve to Count return the value expected?
var httpContextMock = new Mock<HttpContextBase>();
var request = new Mock<HttpRequestBase>();
httpContextMock.SetupGet(x => x.Request).Returns(request.Object);
httpContextMock.SetupGet(x => x.Request.Form).Returns(form);
httpContextMock.SetupGet(x => x.Request.Files.Count).Returns(2);
It is not working because you are setting up the wrong mock. Apply the setup on the request mock.
var httpContextMock = new Mock<HttpContextBase>();
var requestMock = new Mock<HttpRequestBase>();
requestMock.Setup(_ => _.Form).Returns(form);
requestMock.Setup(_ => _.Files.Count).Returns(2);
httpContextMock.Setup(_ => _.Request).Returns(requestMock.Object);
Just to prove the above works, I tested it like this
var context = httpContextMock.Object;
Assert.AreEqual(2, context.Request.Files.Count);
and it worked.
I did a quick test and it works if you access the request through the mock context.
[Test()]
public void Test()
{
var httpContextMock = new Mock<HttpContextBase>();
var request = new Mock<HttpRequestBase>();
httpContextMock.SetupGet(x => x.Request).Returns(request.Object);
httpContextMock.SetupGet(x => x.Request.Files.Count).Returns(2);
var count = httpContextMock.Object.Request.Files.Count;
Assert.AreEqual(2, count);
}
As Nkosi suggested, however, you probably wanted to setup Files.Count on the requestMock itself.

Why is my Moq not returning null?

My Moq is returning data I don't expect.
var artist = new Artist();
artist.Id = "4576";
var deserializer = Mock.Of<IXmlDeserializer<Album>>(
d => d.Deserialize("foo").Artist == artist);
Assert.IsNull(deserializer.Deserialize(null));
The above test fails.
The really puzzling thing is that the mock returns a Mock but that
Assert.AreEqual("4576", deserializer.Deserialize(null).Artist.Id)
returns true.
It's as if the "default" returned by my mock for an unspecified argument (in this case null) was somehow influenced by what I told it to return when called with "foo".
You can either write:
var artist = new Artist { Id = "4576" };
var mock = new Mock<IXmlDeserializer<Album>>();
mock.Setup(x => x.Deserialize(It.Is<string>(i => i == "foo"))).Returns(new Album() { Artist = artist });
var deserializer = mock.Object;
Assert.IsNull(deserializer.Deserialize(null));
Assert.IsNotNull(deserializer.Deserialize("foo"));
Or using the Mock.Of() syntax the above would be:
var artist = new Artist { Id = "4576" };
var deserializer = Mock.Of<IXmlDeserializer<Album>>(d => d.Deserialize(It.Is<string>(i => i == "foo")) == Mock.Of<Album>(album => album.Artist == artist));
Assert.IsNull(deserializer.Deserialize(null));
Assert.IsNotNull(deserializer.Deserialize("foo"));
Assert.AreEqual("4576", deserializer.Deserialize("foo").Artist.Id);

Automapper - RecognizePrefixes doesn't work

I have need to map PriorityId -> TcTaskPriorityId
Mapper.Configuration.RecognizePrefixes("TcTask");
Mapper.CreateMap<Task, TpTasksEntity>();
Task t = new Task{PriorityId = 1};
var te = Mapper.Map<Task, TpTasksEntity>(t);
It just does not work.
The RecognizePrefixes works for source object prefixes, i.e.:
Mapper.Configuration.RecognizePrefixes("TcTask");
Mapper.CreateMap<Task, TpTasksEntity>();
Task t = new Task { TcTaskPriorityId = 1 };
var te = Mapper.Map<Task, TpTasksEntity>(t);
For your scenario you could write a custom naming convention:
Mapper.Configuration.SourceMemberNameTransformer = s => "TcTask" + s;
Mapper.CreateMap<Task, TpTasksEntity>();
Task t = new Task { PriorityId = 1 };
var te = Mapper.Map<Task, TpTasksEntity>(t);
Use RecognizeDestinationPrefixes method.
Can you try:
Mapper.Initialize(cfg => {
cfg.RecognizePrefixes("TcTask");
cfg.CreateMap<Task, TpTasksEntity>();
});

Categories

Resources