How can I cover all the exceptions from various injected services by writing only one unit test?

Viewed 34

I'm testing a method that is of structure like this:

public IActionResult MethodBeingTest(RequestModel req){
   try{
      var value1=_serviceA.Method1();
      var value2=_serviceB.Method2();
      var value3=_serviceC.Method3();

      return CreateResponse(value1+value2+value3);
   }catch(Exception ex){
      return CreateBadResponse("Something bad happened.");
   }
}

In order to check if any of the injected services throws so that a BadResponse is created, I wrote a test like this:

[Fact]
public void MethodBeingTest_ServicesThrow_ReturnBadResponse(){
   Exception ex=new("Something bad happened.");
   mockServiceA.Setup(x=>x.Method1()).Throws(ex);
   mockServiceB.Setup(x=>x.Method2()).Throws(ex);
   mockServiceC.Setup(x=>x.Method3()).Throws(ex);

   //...
}

Obviously, my test will in fact only detect that BadResponse is created when Method1() throws but will never tell what if Method2() and Method3() throw. However, I don't want to write three testing methods for this as it looks foolishly redundant.

Is there a way to do that? Is it possible to write a theory test that only Setup() the method to be tested each time?

Please help.

1 Answers

One way you could accomplish this is by using Theory and InlineData to introduce some parameters to the test that determine when the mocked methods throw an exception. If you went that route, it might look something like this:

[Theory]
[InlineData(true, false, false)]
[InlineData(false, true, false)]
[InlineData(false, false, true)]
public void MethodBeingTest_ServicesThrow_ReturnBadResponse(
   bool serviceAShouldThrow,
   bool serviceBShouldThrow,
   bool serviceCShouldThrow)
{
   Exception ex=new("Something bad happened.");

   if (serviceAShouldThrow) {    
      mockServiceA.Setup(x=>x.Method1()).Throws(ex);
   }

   if (serviceBShouldThrow) {
      mockServiceB.Setup(x=>x.Method2()).Throws(ex);
   }

   if (serviceCShouldThrow) {
      mockServiceC.Setup(x=>x.Method3()).Throws(ex);
   }

   //...
}
Related