Unit testing of internal exceptions

I am writing some unit tests using the integrated Visual Studio framework. I need to write some test cases that are passed when the correct exception is thrown. The problem is that the exceptions I need to check are internal exceptions nested in a more general one. Is there some simple solution or do I need to expand all the functionality. I am currently using the [ExpectedException] attribute, but in such a situation it will not be very good.

I am also interested in what happens when we use [ExpectedException], while we also have some Assert logic in the test itself. Are both conditions satisfied (an exception is thrown and the Assert statement turned out to be valid) or does the test pass immediately after the correct exception is thrown?

+13
c # unit-testing entity-framework
source share
5 answers

If your framework does not support custom casting, you usually have two options:

  1. Implement it yourself
  2. Change (or expand) the structure

I will start with the second solution. Consider using the FluentAssertions library. This allows you to do something like this:

Action deleteUser = () => usersRepository.Delete(new User { Id = null }); deleteUser .ShouldThrow<UserNotFoundException>() .WithInnerException<ArgumentNullException>() .WithInnerMessage("User Id must have value"); 

You will continue to use the Visual Studio testing environment, you just have one additional library for well-spoken statements.

On the other hand, the first choice is a bit more work, as is usually the case with manually untwisted solutions:

 try { usersRepository.Delete(new User { Id = null }); Assert.Fail("Deleting user with null id should throw"); } catch (UserNotFoundException ue) { Assert.AreEqual(ue.InnerException.Message, "User Id must have value"); } 

The ExpectedException attribute is replaced with user code that confirms the actual instance of the exception. As I said, this is more work, but it does its job.

+14
source share

Not a complete solution, but in Nunit you can do such things

  var ex = Assert.Throws<Exception>(() => thing.ThatThrows()); Assert.That(ex.InnerException, Is.TypeOf<BadException>() ); 

Perhaps you can in your test environment?

+15
source share

This is an old question, but I want to share with you my reputation as ExpectedInnerExceptionAttribute with you guys. may be useful for someone

 public class ExpectedInnerExceptionAttribute : ExpectedExceptionBaseAttribute { public ExpectedInnerExceptionAttribute(Type exceptionType) { this.ExceptionType = exceptionType; } public Type ExceptionType { get; private set; } protected override void Verify(Exception ex) { if (ex != null && ex.InnerException != null && ex.InnerException.GetType() == this.ExceptionType) { return; } throw ex; } } 

You can also expand it to check for an exception message, etc. you just need to add your own logic to the Verify method.

+3
source share

For unit testing, I'm currently using FluentAssertions . Since I found out about this, I never wanted to approve the material in any other way.

For exceptions, look at this bit of documentation

In particular, this part

 Action act = () => subject.Foo2("Hello"); act.ShouldThrow<InvalidOperationException>() .WithInnerException<ArgumentException>() .WithInnerMessage("whatever") 
+1
source share

Just use GetAwaiter() and GetResult() to check for an internal exception:

 Assert.Throws<InnerException>(() => thing.GetAwaiter().GetResult()); 

eg

 Assert.Throws<CommunicationException>(() => thing.GetAwaiter().GetResult()); 
0
source share

All Articles