C# 预计最低起订量:<;系统异常>;但是:没有抛出异常

C# 预计最低起订量:<;系统异常>;但是:没有抛出异常,c#,asp.net-core,nunit,moq,C#,Asp.net Core,Nunit,Moq,我有一个有效的单元测试函数。当我合并ILogger和Moq框架时,它不再捕获异常。请参阅下面的最后一个测试。在逐步调试单元测试时,我知道会引发异常。所以不确定为什么它没有显示在Nunit中并导致错误 错误: Message: Expected: <System.ArgumentException> But was: no exception thrown using System; using ElectronicsStore.Models; using Microso

我有一个有效的单元测试函数。当我合并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;
        }       
    }
}
消息:应为:但为:未引发异常
使用制度;
使用电子存储。模型;
使用Microsoft.Extensions.Logging;
名称空间ElectronicsStore.Service
{
公共类供应商供应
{
专用只读ILogger\u记录器;
公共供应商供应(ILogger记录器)
{
_记录器=记录器;
}
公共供应商从CSV供应(字符串CSV行)
{
VendorSupply VendorSupply=新VendorSupply();
尝试
{
字符串[]值=csvLine.Split(',');
如果(值.Length>3)
{
抛出新的System.ArgumentException(“数据太多”);
}
vendorsupply.VendorId=Convert.ToInt16(值[0]);
vendorsupply.ProductId=Convert.ToInt16(值[1]);
供应商供应数量=转换为16(值[2]);
}
捕获(例外)
{
_logger.LogInformation(“尝试时引发异常”);
}
退货供应商供应;
}       
}
}
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
公共类ParseVendorSupplyUnit
{
ILogger记录器;
//这很有效
[测试]
来自CSV_parsed()的公共void
{
var logger=newmock();
var parseVendorSupply=新的parseVendorSupply(logger.Object);
字符串csvLineTest=“5,8,3”;
VendorSupply VendorSupply=parseVendorSupply.FromCsv(csvLineTest);
Assert.AreEqual(5,vendorsupply.VendorId);
Assert.AreEqual(8,vendorsupply.ProductId);
断言.AreEqual(3,供应商供应量);
}
//添加ILogger和Moq后,这不再有效
[测试]
来自CSV的公共无效\u正确解析\u外部数据()
{
var logger=newmock();
var parseVendorSupply=新的parseVendorSupply(logger.Object);
字符串csvLineTest=“5,8,3,9,5”;
Assert.That(()=>parseVendorSupply.fromsv(csvLineTest),Throws.ArgumentException);
}
消息:应为:但为:未引发异常

您的代码在try-catch块中抛出异常。因此,抛出的异常不会离开函数作用域。因此,单元测试失败

        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");
        }
您可以重新浏览
ArgumentException
查看此以获得进一步的指导。但是在方法内部使用exception进行“通信”是一个坏主意。因此,您可以简单地移动参数检查,使其位于try-catch块之外

希望这有帮助(这与最低起订量无关)我想您已经意识到,您在代码中添加了一个
try…catch
块,该块接受异常;但是您不明白为什么抛出特定异常的断言现在失败了。毕竟,您仍然在抛出异常,所以您想知道为什么NUnit没有注意到

NUnit不能通过观察代码在执行时所做的操作来工作。它可以判断是否引发异常的唯一方法是,该异常是否出现在调用代码中(调用代码是在测试方法中引发异常的断言)

您可以将抛出的
ArgumentException
断言视为捕获(ArgumentException)。由于新代码吞没了异常,测试中的断言永远看不到异常,因此断言失败

作为一个与设计相关的补充说明,看看在抛出异常时代码的行为。调用者只是返回一个对象(就像它工作过一样)。因此调用代码不会意识到任何错误(我认为这是一个糟糕的设计)

您可以使用Moq来验证LogInformation方法是否被调用过一次;但这可能是由不同的异常引起的

<>也值得指出的是,在一个明确地阻止程序运行的东西上调用<代码> Logix/<代码>是一个有趣的选择。日志信息用于可能感兴趣的事物。考虑在记录器上使用不同的方法,我建议日志错误或更糟。

什么是代码> catch(异常)。do?