105

I'm developing a Web API, and one of the test I came up with is that, if client makes a GET operation with a Physical Test ID (Physical Test is the resource I'm looking for) and that physical test is not found, the web API should return a 404 status.

Now, I'm using moq framework for my tests and I have the following code:

[TestMethod]
public void then_if_physical_test_not_found_return_not_found_status()
{
    var unitOfWork = new Mock<IUnitOfWork>();
    var repository = new Mock<IRepository<PhysicalTest>>();
    repository.Setup(r => r.FindById(It.IsAny<int>())).Returns();
    unitOfWork.Setup(m => m.PhysicalTests).Returns(repository.Object);
    var pt = new PhysicalTestResource(unitOfWork.Object);
    HttpResponseMessage<PhysicalTest> response = pt.GetPhysicalTest(43);
    Assert.AreEqual(HttpStatusCode.NotFound, response.StatusCode)
}

I need the Returns() method to return a null object, which is going to be what the actual API method would return if the resource is not found.

I tried sending null as a parameter in the Returns() method but had no success.

1
  • To clarify, the error occurs because there are two overloads of Returns, one taking T (T = IRepository<PhysicalTest> in this case) and one taking Func<T>. When passing null, the compiler doesn't know which one to use, so you have to be specific. These overloads exist to give you the option to either return a static value .Returns(new T()) or a new instance on every call .Returns(() => new T()). Commented Jul 20, 2022 at 8:25

7 Answers 7

300

You don't indicate what the error was, but this should work:

unitOfWork.Setup(m => m.PhysicalTests).Returns((IRepository<PhysicalTest>)null);

I suspect you tried to call it with Returns(null), which causes the compiler to complain since Returns is overloaded and it doesn't know which method should be called. Casting to a specific type removes the ambiguity.

Sign up to request clarification or add additional context in comments.

5 Comments

it worked, but I had to make this modification: unitOfWork.Setup(m => m.PhysicalTests).Returns((PhysicalTest)null);
ah, ok... I assumed that since you were trying to return repository.Object that was the type returned by PhysicalTests.
I tried the same thing and I'm getting a System.NotSupportedException. {"Invalid setup on a non-virtual (overridable in VB) member: x => x.GetFoo(.value.Id)"} Any ideas?
@DanCsharpster You can only use Moq on interfaces or abstract classes with virtual members. Whatever class you're using that is the type of x is either a concrete class or an abstract class that has GetFoo() as non-virtual/overridable.
I can recommend this way of resolving the overload ambiguity. I just want to mention that, since the two non-generic overloads of Returns which are important here, have different names for their parameter, you can also resolve the ambiguity by writing: ... .Returns(value: null) (here value is just the name of the parameter in the overload we want, it is not a keyword).
13

If you are receiving an error like this:

enter image description here

You just need to specify the input parameter of 'Returns' method. Take a look in my example:

_ = _fileStorage.Setup(x => x.LoadDocument(It.IsAny<string>())).Returns(value: null);

Comments

12

rt is a return type of method: FindById

repository.Setup(r => r.FindById(It.IsAny<int>())).Returns(Task.FromResult((rt)null));

Comments

5

Organization is a return type of method: Get

mockCache
    .Setup(cache => cache.Get(It.IsAny<string>(), It.IsAny<string>(),It.IsAny<string>()))
    .Returns(value: null as Organization);

Comments

2

Along with casting the member to null as mentioned by the accepted answer, this approach should work as well.

unitOfWork.Setup(m => m.PhysicalTests).Returns(() => null);

Comments

0

You could try this:

ref1.Setup(s => s.Method(It.IsAny<Ref2>(), It.IsAny<string>()))
     .Returns((Task<Ref3>)null);

ref1 = Mock Interface
Ref2 = Type request parameter
Ref3 = Type of return method mock

Comments

0

You're too close, you only need to pass the return type as generic type like so

repository.Setup(r => r.FindById(It.IsAny<int>())).Returns<IRepository<PhysicalTest>>(null);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.