c# - Assert.Throws 方法没有捕捉到预期的异常
问题描述
我正在尝试测试一个非常简单的功能。它返回包含某些指定数字的数字。如果第一个参数是null
,它会抛出ArgumentNullException
。
不幸的是,Assert.Throws
没有抛出预期的异常并且测试失败。当我尝试调试测试时,它不会进入我的方法。与ArgumentException
.
只有最后两个测试失败,其他测试成功。
我要测试的功能:
/// <summary>
/// Filter given numbers and return only numbers containing the specified digit.
/// </summary>
/// <param name="numbers">The numbers to be filtered.</param>
/// <param name="digit">The digit which should be found.</param>
/// <returns>Numbers that contains the digit.</returns>
/// <exception cref="ArgumentException"> Thrown if the digit value isn't between 0 and 9.</exception>
/// <exception cref="ArgumentNullException"> Thrown if numbers are null.</exception>
public static IEnumerable<int> FilterDigits(IEnumerable<int> numbers, byte digit)
{
if (numbers == null)
{
throw new ArgumentNullException();
}
foreach (int number in numbers)
{
if (number.ContainsDigit(digit))
{
yield return number;
}
}
}
/// <summary>
/// Check whether the number contains the given digit.
/// </summary>
/// <param name="number">The number which can contain the digit.</param>
/// <param name="digit">The digit to be found.</param>
/// <returns>True if the number contains the digit, else false.</returns>
/// <exception cref="ArgumentException"> Thrown if the digit value isn't between 0 and 9.</exception>
/// <example> ContainsDigit(10, 1) -> true </example>
/// <example> ContainsDigit(10, 2) -> false </example>
private static bool ContainsDigit(this int number, byte digit)
{
if (!char.TryParse(digit.ToString(), out char digitChar))
{
throw new ArgumentException("The digit should be from 0 to 9.");
}
string numberString = number.ToString();
foreach (char ch in numberString)
{
if (ch == digitChar)
{
return true;
}
}
return false;
}
我的测试课:
[TestFixture]
public class DigitsFilterTests
{
[TestCase(new int[] { 1, 4, 23, 346, 7, 23, 87, 71, 77 }, 7, ExpectedResult = new int[] { 7, 87, 71, 77 })]
[TestCase(new int[] { 345, 4, 0, 90, 709 }, 0, ExpectedResult = new int[] { 0, 90, 709})]
public IEnumerable<int> FilterDigits_NumbersContainDigit(int[] numbers, byte digit)
=> DigitsFilter.FilterDigits(numbers, digit);
[TestCase(new int[] { 1, 4, 222, 9302 }, 7, ExpectedResult = new int[] { })]
[TestCase(new int[] { 345, 4, 354, 25, 5 }, 0, ExpectedResult = new int[] { })]
public IEnumerable<int> FilterDigits_NumbersNotContainDigit(int[] numbers, byte digit)
=> DigitsFilter.FilterDigits(numbers, digit);
[TestCase(new int[] { }, 0, ExpectedResult = new int[] { })]
public IEnumerable<int> FilterDigits_EmptyList(int[] numbers, byte digit)
=> DigitsFilter.FilterDigits(numbers, digit);
[Test]
public void FilterDigits_NullNumbers_ArgumentNullException()
=> Assert.Throws<ArgumentNullException>(() => DigitsFilter.FilterDigits(null, 5));
[Test]
public void FilterDigits_InvalidDigit_ArgumentException()
=> Assert.Throws<ArgumentException>(() => DigitsFilter.FilterDigits(new int[] { }, 10));
}
解决方案
您的方法是使用yield return
. 棘手的是,除非您枚举它,否则实际上什么都不会发生。
因此,您必须确保您的测试枚举内容:
[Test]
public void FilterDigits_NullNumbers_ArgumentNullException()
=> Assert.Throws<ArgumentNullException>(() => DigitsFilter.FilterDigits(null, 5).ToList());
ContainsDigit
此外,无论哪种方式,您的第二次测试都会失败,因为如果numbers
为空,您将无法到达。
如果要修复方法内部的行为,则需要将其分为两部分:
public static IEnumerable<int> FilterDigits(IEnumerable<int> numbers, byte digit)
{
if (numbers == null)
{
throw new ArgumentNullException();
}
return FilterDigitsImpl(numbers, digit);
}
private static IEnumerable<int> FilterDigitsImpl(IEnumerable<int> numbers, byte digit)
{
foreach (int number in numbers)
{
if (number.ContainsDigit(digit))
{
yield return number;
}
}
}
如果您的 C# 版本足够新,则可以使用本地函数合并这两种方法:
public static IEnumerable<int> FilterDigits(IEnumerable<int> numbers, byte digit)
{
if (numbers == null)
{
throw new ArgumentNullException();
}
IEnumerable<int> FilterDigitsImpl()
{
foreach (int number in numbers)
{
if (number.ContainsDigit(digit))
{
yield return number;
}
}
}
return FilterDigitsImpl();
}
推荐阅读
- spartacus-storefront - 如何正确覆盖默认的 spartacus 组件
- google-sheets - 如果选中复选框,则突出显示列的公式 - Google 表格
- powershell - Powershell 不会在电子邮件 html 正文中输出“£”
- scala - Apache Spark根据列的不同值计算列值
- gcc - 用于堆栈与堆访问的 gcc 程序集
- android - RecyclerView 仅显示两个文本视图?其他不显示...项目不显示
- python - 为什么 Pycharm 不突出 TODO 的?
- html - 将一个元素放在另一个垂直居中的下方
- c - 指向作为函数参数的指针的指针
- excel - ADODB Stream 将二进制转换为字符串