最小起订量:<system.argumentexception>,但没有:没有引发异常

时间:2018-11-13 05:18:36

标签: c# asp.net-core nunit moq

我有一个有效的单元测试功能。当我合并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

2 个答案:

答案 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方法中断言正在抛出异常的断言)。

您可以认为您断言ArgumentExceptioncatch(ArgumentException)的断言。并且由于您的新代码吞没了异常,所以测试中的断言将永远不会看到,因此断言将失败。

作为与设计有关的附带说明,请查看抛出该异常时代码的行为。调用者只是取回一个对象(就像它已经起作用一样)。因此,调用代码不会意识到有任何问题(我建议这是一个错误的设计)。

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

还值得指出的是,在某个显然会阻止程序运行的东西上调用LogInformation是一个有趣的选择。 LogInformation适用于可能感兴趣的事情。考虑在记录器上使用其他方法,建议使用LogError或更糟糕的方法。