有很多关于 Nunit 和测试异常的线程。但是,我无法弄清楚如何将其应用到我的特定代码上。该参数给我带来了一些麻烦。
我抛出的异常看起来像这样:
throw new ArgumentOutOfRangeException(paramName: nameof(valueMayNotBeZero), message: "The argument must have a positive value!");
非常感谢指导和评论。
在此示例中,我创建一个异常对象并根据我的实际字符串检查属性
Message
。这似乎有点尴尬。但这是我运行测试的唯一方法。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!"));
}
}
为什么需要测试异常?
在我当前的项目中,我有接收
double
作为参数的方法。如果该值为 <= 0
,则抛出异常。由于我刚开始进行单元测试,我认为这种情况也必须进行测试。
public static double CalculateEmployerStatutoryPensionContribution(double grossSalary)
{
if (grossSalary <= 0)
{
throw new ArgumentOutOfRangeException(nameof(grossSalary), "The argument must have a positive value!");
}
return grossSalary * RentenversichungArbeitgeberPflichtanteil;
}
考虑到您的最后一个例子,我尝试回答您问题的最后部分。首先,您必须测试您的逻辑而不是 .NET
ArgumentOutOfRangeException
。
为此,您应该创建三个不同的场景来测试可以找到 grossSalary
值的所有情况,如下所示:
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
});
}
}
谢谢您的回复!
我需要使用这些 lamda 表达式进行大量训练。
我的一次尝试确实是这样的。由于语法使用不正确,它不起作用。
Assert.Throws<ArgumentOutOfRangeException>(() =>
BusinessMiniJob.CalculateEmployeeSalary(valueMayNotBeZero),
"The argument must have a positive value!");
Luca 的代码确实看起来像这样(根据我当前的测试进行了修改)。这段代码工作正常。对我来说,这是一个比我想象的更好、更易读的解决方案(参见线程顶部)。
Assert.Throws<ArgumentOutOfRangeException>(() =>
{
BusinessMiniJob.CalculateEmployeeSalary(grossSalary);
}, "The argument must have a positive value!");
这里我正在测试例外情况。
private static IEnumerable<double> SourceProviderException()
{
// GrossSalary
yield return 0.0;
yield return -10.0;
}
[TestCaseSource(nameof(SourceProviderException))]
public void EmployerStatutoryPensionContributionTest_ThrowsException(double grossSalary)
{
// ***** Arrange *****
// ***** Act & Assert *****
Assert.Throws<ArgumentOutOfRangeException>(() =>
{
BusinessMiniJob.CalculateEmployerStatutoryPensionContribution(grossSalary);
}, "The argument must have a positive value!");
}
这里我正在测试该方法的计算。提供
grossSalary
并列出预期结果。 (在这种情况下,有一些参数我没有使用;还有更多方法使用相同的SourceProvider
)。
private static IEnumerable<double[]> SourceProvider()
{
// GrossSalary, Salary, EmployeeStatutoryPensionContribution, EmployerStatutoryPensionContribution
yield return new[] { 175.00, 168.70, 6.30, 26.25 };
yield return new[] { 150.00, 139.95, 10.05, 22.50 };
yield return new[] { 25.00, -3.80, 28.80, 3.75 };
}
[TestCaseSource(nameof(SourceProvider))]
public void EmployerStatutoryPensionContributionTest(double grossSalary, double salary, double employeeContribution, double employerContribution)
{
// ***** Arrange *****
// ***** Act *****
var result = BusinessMiniJob.CalculateEmployerStatutoryPensionContribution(grossSalary);
// ***** Assert *****
Assert.That(result.ToString("c2"), Is.EqualTo(employerContribution.ToString("c2")));
}