Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
How to verify an exception that has been thrown in unit testing C#?
Unit testing in C# requires verifying that methods throw expected exceptions under certain conditions. There are two primary approaches to verify exceptions in MSTest: using Assert.ThrowsException and using the ExpectedException attribute.
Both methods allow you to test that your code properly handles error conditions and throws appropriate exceptions when invalid input or unexpected scenarios occur.
Syntax
Using Assert.ThrowsException method −
var exception = Assert.ThrowsException<ExceptionType>(() => methodCall);
Assert.AreEqual("Expected message", exception.Message);
Using ExpectedException attribute −
[ExpectedException(typeof(ExceptionType), "Expected message")]
[TestMethod]
public void TestMethod() {
// method call that should throw exception
}
Sample Method for Testing
Let us consider a StringAppend method that throws an exception which needs to be tested −
using System;
namespace DemoApplication {
public class Program {
static void Main(string[] args) {
}
public string StringAppend(string firstName, string lastName) {
if (firstName == null || lastName == null) {
throw new ArgumentNullException("Parameters cannot be null");
}
throw new Exception("Test Exception");
}
}
}
Using Assert.ThrowsException
The Assert.ThrowsException method captures the thrown exception and allows you to verify both the exception type and its properties −
using System;
using DemoApplication;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace DemoUnitTest {
[TestClass]
public class DemoUnitTest {
[TestMethod]
public void TestStringAppendThrowsException() {
Program program = new Program();
var ex = Assert.ThrowsException<Exception>(() => program.StringAppend("Michael", "Jackson"));
Assert.AreEqual("Test Exception", ex.Message);
}
}
}
In this example, we call the StringAppend method using Assert.ThrowsException and validate both the exception type and message. The test passes because the method throws the expected exception.
Using ExpectedException Attribute
The ExpectedException attribute decorates the test method to specify the expected exception type and message −
using System;
using DemoApplication;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace DemoUnitTest {
[TestClass]
public class DemoUnitTest {
[TestMethod]
[ExpectedException(typeof(Exception), "Test Exception")]
public void TestStringAppendWithExpectedException() {
Program program = new Program();
program.StringAppend("Michael", "Jackson");
}
}
}
In this example, we use the ExpectedException attribute to specify the expected exception type and message. Since the StringAppend method throws the same type of exception mentioned in the attribute, the test passes.
Comparison
| Assert.ThrowsException | ExpectedException Attribute |
|---|---|
| More flexible - can inspect exception properties | Simple declarative approach |
| Can verify specific parts of exception details | Limited to type and message validation |
| Better error reporting and debugging | Less precise error information |
| Recommended modern approach | Legacy approach, less preferred |
Testing Specific Exception Types
Here's an example testing a more specific exception type −
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace ExceptionTest {
public class Calculator {
public int Divide(int a, int b) {
if (b == 0) {
throw new DivideByZeroException("Cannot divide by zero");
}
return a / b;
}
}
[TestClass]
public class CalculatorTests {
[TestMethod]
public void TestDivideByZero() {
Calculator calc = new Calculator();
var ex = Assert.ThrowsException<DivideByZeroException>(() => calc.Divide(10, 0));
Assert.AreEqual("Cannot divide by zero", ex.Message);
}
}
}
Conclusion
Both Assert.ThrowsException and ExpectedException attribute allow you to verify exceptions in unit tests. The Assert.ThrowsException method is preferred as it provides better control over exception validation and more detailed error reporting when tests fail.
