I am using moq version 4.2 to unit test some controllers of web api 2 with EF as the ORM. Since a lot of tests need a mocked IEntityRepository<User>
so I use a static method in a separate class called TestHelper
to create such a fake repository so that I can just call this method in all the tests where needed. Here is the static method:
internal static IEntityRepository<User> GetSingleUserMockRepository(User user, bool noTracking = true, params Expression<Func<User, object>>[] properties)
{
var userRepository = new Mock<IEntityRepository<User>>();
if (properties.Any())
userRepository.Setup(x => x.GetSingleInclude(user.Key, noTracking, properties)).Returns(Task.FromResult(user));
else
userRepository.Setup(x => x.GetSingle(user.Key, noTracking)).Returns(Task.FromResult(user));
return userRepository.Object;
}
I am not showing other method details here because don't think they're relevant to my problem. The thing is when calling this static method in my tests and pass the returned user repository into controllers the test will fail because it cannot find the user i.e. Setup
didn't work!. However, if I repeat the test implementation within my tests to create the mock repository as a local variable; everything works fine.
Namely, this doesn't work (where Devices
is a navigation property on the User entity, again don't think the detail matters here) e.g. if I pass the returned userRepository
into my controller the test will fail.:
var userRepository = TestHelper.GetSingleUserMockRepository(user, true, x=> x.Devices);
But this works e.g. if I just use a local variable in the test and pass the userRepository.Object
into my controller everything works as expected:
var userRepository = new Mock<IEntityRepository<User>>();
userRepository.Setup(x => x.GetSingleInclude(user.Key, true, u => u.Devices)).Returns(Task.FromResult(user));
Can someone please explain why? I thought these two ways are equivalent but clearly not in practice.