如何用Xunit测试C#除法方法中的DivideByZeroException异常?
问题原因与解决方案
你的单元测试无法通过的核心原因是:Divide方法内部已经捕获了DivideByZeroException并仅打印日志,没有将异常向外抛出,所以测试代码里的Assert.Throws根本捕获不到异常。
下面分两种场景给出解决办法:
方案一:修正原方法,让异常向外抛出(推荐)
原方法的设计存在缺陷——除零错误发生后,调用方完全无法感知,只会得到一个错误的计算结果。正确的做法是让异常向外抛出,或者至少让调用方知晓错误发生。
修改后的Divide方法:
public void Divide(CalculatorData calculate) { calculate.Operator = CalculatorOperator.Divide; calculate.calculatorResult = calculate.inputNumbers[0]; for (int i = 1; i < calculate.inputNumbers.Length; i++) { decimal item = calculate.inputNumbers[i]; if (item == 0) { throw new DivideByZeroException("除数不能为零"); } calculate.calculatorResult /= item; } }
如果需要保留日志打印,可以捕获后重新抛出:
public void Divide(CalculatorData calculate) { calculate.Operator = CalculatorOperator.Divide; calculate.calculatorResult = calculate.inputNumbers[0]; for (int i = 1; i < calculate.inputNumbers.Length; i++) { decimal item = calculate.inputNumbers[i]; try { calculate.calculatorResult /= item; } catch (DivideByZeroException e) { Console.WriteLine(e.Message); throw; // 重新抛出异常,让调用方可以捕获 } } }
对应的修正后测试代码:
public void Divide_DivByZero() { // Arrange calculatorData.inputNumbers = new[] { 5m, 0m }; // Act & Assert Assert.Throws<DivideByZeroException>(() => calculatorManager.Divide(calculatorData)); }
方案二:不修改原方法,调整测试逻辑(不推荐)
如果必须保留原方法的现有行为,测试不能断言抛出异常,而是要验证方法处理除零后的实际结果:
public void Divide_DivByZero_Handled() { // Arrange calculatorData.inputNumbers = new[] { 5m, 0m }; calculatorData.calculatorResult = 0; // 重置初始值 // Act calculatorManager.Divide(calculatorData); // Assert Assert.Equal(5m, calculatorData.calculatorResult); // 除零被捕获后,结果保持初始的第一个输入值 }
内容的提问来源于stack exchange,提问作者AndreaMarinas
相关产品推荐
相关产品推荐

