afl aflavich
afl aflavich

Reputation: 23

Is there a way to spy on if a method caught an exception using Moq.NET?

My original method looks something like the following pseudo-code:

public bool IsValid(){
  try{
   // logic
  } catch (Exception){
   return false;
  }
}

Every time my logic throws any type of exception, then false will be returned. For example, in my unit tests I pass a null string and then assert that the returned value is false. However, is there any way to also check that the exception was thrown, even though it got caught?

Upvotes: 0

Views: 279

Answers (1)

David
David

Reputation: 219057

You don't need a mocking library for this. It's not really a technology issue, but a logical one. Consider your statement:

Every time my logic throws any type of exception, then false will be returned.

Validating this is simply asserting that the returned value is false. No mocks, no digging into the innards of the framework, none of that. Keeping in mind that we don't know that the "logic" is in this method, the idea is simply that the "Arrange" step of your unit test would set up a scenario in which an exception would be thrown by the logic and the "Assert" step would validate that false is the result of the operation.

Consider that unit tests are themselves just consuming code for a component. They shouldn't know or care about the internals of that component. What you have is a scenario where you are defining two conflicing things:

  1. I don't want consuming code to ever know if an exception is thrown, it should just return false.
  2. I have consuming code which should know if an exception was thrown.

One of those two things needs to change.

Note also that you don't necessarily need to change the returned behavior of the method in order to change this testable validation. For example, you could simply introduce a logging dependency to the component and, within your catch block, log the exception. Then your unit test can mock that dependency and assert that an exception was logged.

Basically, your unit tests validate externally-observable results of an operation. So in order to validate something, it needs to be externally observable. Either as a thrown exception, or a returned value, or an invoked operation on a dependency, or some other observable change in the state of the system. If you need to observe it, then it needs to do something observable. Or, if it shouldn't do anything observable then you don't need to observe it.

Upvotes: 1

Related Questions