我有一个有效的单元测试功能。当我合并ILogger和Moq框架时,它不再捕获异常。请参阅下面的最后测试。在逐步调试单元测试中,我知道抛出了异常。因此不确定为什么它不显示在Nunit中并导致错误。
错误:
Message: Expected: <System.ArgumentException> But was: no exception thrown
using System;
using ElectronicsStore.Models;
using Microsoft.Extensions.Logging;
namespace ElectronicsStore.Service
{
public class ParseVendorSupply
{
private readonly ILogger _logger;
public ParseVendorSupply(ILogger logger)
{
_logger = logger;
}
public VendorSupply FromCsv(string csvLine)
{
VendorSupply vendorsupply = new VendorSupply();
try
{
string[] values = csvLine.Split(',');
if (values.Length > 3)
{
throw new System.ArgumentException("Too much data");
}
vendorsupply.VendorId = Convert.ToInt16(values[0]);
vendorsupply.ProductId = Convert.ToInt16(values[1]);
vendorsupply.Quantity = Convert.ToInt16(values[2]);
}
catch (Exception)
{
_logger.LogInformation("An exception was thrown attempting");
}
return vendorsupply;
}
}
}
NUnit测试:
public class ParseVendorSupplyNunit
{
ILogger logger;
// This Works
[Test]
public void FromCsv_ParseCorrectly()
{
var logger = new Mock<ILogger>();
var parseVendorSupply = new ParseVendorSupply(logger.Object);
string csvLineTest = "5,8,3";
VendorSupply vendorsupply = parseVendorSupply.FromCsv(csvLineTest);
Assert.AreEqual(5, vendorsupply.VendorId);
Assert.AreEqual(8, vendorsupply.ProductId);
Assert.AreEqual(3, vendorsupply.Quantity);
}
// This does not work anymore,after adding ILogger and Moq
[Test]
public void FromCsv_ParseCorrectly_Extradata()
{
var logger = new Mock<ILogger>();
var parseVendorSupply = new ParseVendorSupply(logger.Object);
string csvLineTest = "5,8,3,9,5";
Assert.That(() => parseVendorSupply.FromCsv(csvLineTest), Throws.ArgumentException);
}
Message: Expected: <System.ArgumentException> But was: no exception thrown
答案 0 :(得分:1)
您的代码在try-catch块中引发异常。因此,抛出的异常不会离开函数范围。由于单元测试失败。
create
您可以将 try
{
string[] values = csvLine.Split(',');
if (values.Length > 3)
{
throw new System.ArgumentException("Too much data");
}
vendorsupply.VendorId = Convert.ToInt16(values[0]);
vendorsupply.ProductId = Convert.ToInt16(values[1]);
vendorsupply.Quantity = Convert.ToInt16(values[2]);
}
catch (Exception)
{
_logger.LogInformation("An exception was thrown attempting");
}
重新扔到stackoverflow link中以获取进一步的指导。但是在方法内部使用异常进行“通信”是一个坏主意。因此,您可以简单地移动参数检查,使其位于try-catch块之外。
希望有帮助
答案 1 :(得分:0)
(这与Moq无关。)我想您知道您已经在代码中添加了一个try...catch
块来吞噬异常;但您不理解为什么现在抛出特定异常的断言失败了。毕竟,您仍然仍然抛出异常,所以您想知道为什么NUnit不会注意到。
NUnit无法通过观察代码在执行时的状态来工作。唯一可以判断是否引发异常的方法是该异常是否在调用代码中起泡(em)(调用代码是在test方法中断言正在抛出异常的断言)。>
您可以认为您断言ArgumentException
是catch(ArgumentException)
的断言。并且由于您的新代码吞没了异常,所以测试中的断言将永远不会看到,因此断言将失败。
作为与设计有关的附带说明,请查看抛出该异常时代码的行为。调用者只是取回一个对象(就像它已经起作用一样)。因此,调用代码不会意识到有任何问题(我建议这是一个错误的设计)。
您可以使用Moq来验证一次LogInformation方法是否被调用;但这可能是由另一个异常引起的。
还值得指出的是,在某个显然会阻止程序运行的东西上调用LogInformation
是一个有趣的选择。 LogInformation适用于可能感兴趣的事情。考虑在记录器上使用其他方法,建议使用LogError或更糟糕的方法。