There are quite a few threads about Nunit and testing exceptions. However, I was not able to figure out how to apply this on my specific code. The parameter are causing me some trouble.
The exception I am throwing looks like this:
throw new ArgumentOutOfRangeException(paramName: nameof(valueMayNotBeZero), message: "The argument must have a positive value!");
Mentoring and comments are much appreciated.
In this example I am creating an exception object and checking the property Message
against my actual string. This seems to be a bit awkward. But this is the only way I got my test running.
var result = Assert.Throws<ArgumentOutOfRangeException>(() => testObject.ThrowAnException(valueMayNotBeZero));
Assert.That(result.Message, Is.EqualTo("The argument must have a positive value! (Parameter 'valueMayNotBeZero')"));
Program.cs
using StackOverflow;
GenerateException demo = new();
try
{
Console.WriteLine($"Value: {demo.ThrowAnException(1.5):f2}");
}
catch (Exception e)
{
Console.WriteLine("Unexpected Exception!");
Console.WriteLine(e);
}
Console.WriteLine($"\n***** Press ENTER To Continue *****");
Console.ReadLine();
GenerateException.cs
namespace StackOverflow;
public class GenerateException
{
public double ThrowAnException(double valueMayNotBeZero)
{
if (valueMayNotBeZero <= 0)
{
throw new ArgumentOutOfRangeException(nameof(valueMayNotBeZero), "The argument must have a positive value!");
}
return valueMayNotBeZero;
}
}
GenerateExceptionTests.cs
using StackOverflow;
namespace SackOverflowTest;
public class GenerateExceptionTests
{
private static IEnumerable<double> SourceProvider()
{
yield return 10.0;
yield return 99.99;
}
private static IEnumerable<double> SourceProviderException()
{
// GrossSalary
yield return 0.0;
yield return -10.0;
}
[TestCaseSource(nameof(SourceProvider))]
public void CreateNoExceptionTest(double valueMayNotBeZero)
{
// ***** Arrange *****
GenerateException testObject = new();
// ***** Act *****
var result = testObject.ThrowAnException(valueMayNotBeZero);
// ***** Assert *****
Assert.That(result, Is.EqualTo(valueMayNotBeZero));
}
[TestCaseSource(nameof(SourceProviderException))]
public void CreateAnExceptionTest(double valueMayNotBeZero)
{
// ***** Arrange *****
GenerateException testObject = new();
// ***** Act *****
var result = Assert.Throws<ArgumentOutOfRangeException>(() => testObject.ThrowAnException(valueMayNotBeZero));
// ***** Assert *****
Assert.That(result.Message, Is.EqualTo("The argument must have a positive value! (Parameter 'valueMayNotBeZero')"));
// somehow not working; logic error?
//Assert.Throws<ArgumentOutOfRangeException>(() => BusinessMiniJob.CalculateEmployeeSalary(valueMayNotBeZero), "The argument must have a positive value!");
//Assert.That(() => Throws.TypeOf<ArgumentOutOfRangeException>().And.Property(nameof(valueMayNotBeZero)).And.Message.Equals("The argument must have a positive value!"));
}
}
Why do I need to test the exception?
In my current project, I have methods receiving a double
as parameter. If this value is <= 0
then the exception is thrown. And since I am at the beginning to work with unit tests, I thought this situation must be tested, too.
public static double CalculateEmployerStatutoryPensionContribution(double grossSalary)
{
if (grossSalary <= 0)
{
throw new ArgumentOutOfRangeException(nameof(grossSalary), "The argument must have a positive value!");
}
return grossSalary * RentenversichungArbeitgeberPflichtanteil;
}
i try to response at the last part of your question, taking into account your last example. First of all, you have to test your logic not the .NET ArgumentOutOfRangeException
.
For do this you should create three different scenario for testing all cases in which the value of grossSalary
can be found, like that:
public class PensionContributionTests
{
[Test]
public void CalculateEmployerStatutoryPensionContribution_NegativeValue_ThrowsException()
{
// Arrange
double negativeGrossSalary = -1000.0; // Adjust the value as needed
// Act & Assert
Assert.Throws<ArgumentOutOfRangeException>(() =>
{
CalculateEmployerStatutoryPensionContribution(negativeGrossSalary);
}, "The argument must have a positive value!");
}
[Test]
public void CalculateEmployerStatutoryPensionContribution_ZeroValue_ThrowsException()
{
// Arrange
double zeroGrossSalary = 0.0; // Adjust the value as needed
// Act & Assert
Assert.Throws<ArgumentOutOfRangeException>(() =>
{
CalculateEmployerStatutoryPensionContribution(zeroGrossSalary);
}, "The argument must have a positive value!");
}
[Test]
public void CalculateEmployerStatutoryPensionContribution_PositiveValue_DoesNotThrowException()
{
// Arrange
double positiveGrossSalary = 5000.0; // Adjust the value as needed
// Act & Assert
Assert.DoesNotThrow(() =>
{
var result = CalculateEmployerStatutoryPensionContribution(positiveGrossSalary);
// You can also add assertions to check the result if needed
});
}
}