Reputation: 33
I want to write an UnitTest with Moq 4.14.7. The method to be tested is as follows:
public IFoo Get(Guid id)
{
Func<IFoo> getData = () => _repository.Get(id);
if (_cache.TryGetAndSet(vaultId, getData, out var result))
{
return result;
}
}
To briefly explain. I have a generic cache class. It checks in the cache if an entity with the passed guid exists. If this is not the case, the repository is called.
Now I have the following setup for the cache:
_cache.Setup
(
x => x.TryGetAndSet
(
_vaultId,
It.IsAny<Func<IFoo>>(),
out foo
)
)
.Returns(true);
The test works so far, but I do not achieve 100% coverage with it, because the func is not covered.
Is there a better way here than to work with It.IsAny
and get 100% coverage?
Upvotes: 2
Views: 676
Reputation: 247018
Capture the arguments passed to the member and invoke the function as desired.
//...
IFoo mockedFoo = Mock.Of<IFoo>();
IFoo foo = null;
_repo.Setup(_ => _.Get(It.IsAny<Guid>()).Returns(mockedFoo);
_cache
.Setup(_ => _.TryGetAndSet(It.IsAny<Guid>(), It.IsAny<Func<IFoo>>(), out foo))
.Returns((Guid vid, Func<IFoo> func, IFoo f) => {
foo = func(); //<-- invoke the function and assign to out parameter.
return true;
});
//...
//Assertion can later verify that the repository.Get was invoked
//Assertion can later assert that foo equals mockedFoo
TryGetAndSet
will return true
, and the out argument will return the mockedFoo, lazy evaluated
Reference Moq Quickstart
Upvotes: 2