System.ArgumentNullException:单元测试中的值不能为空 - C#

System.ArgumentNullException : Value cannot be null in unit test - C#

我在 运行 单元测试时遇到此错误: Error Message: System.ArgumentNullException : Value cannot be null. Parameter name: logger 而且我也收到了这个警告: Field 'OrderControllerTest._logger' is never assigned to, and will always have its default value null

有没有办法让记录器静音或测试它?

对编程还是个新手,渴望学习。已经为此苦苦挣扎了很长时间。感谢您的帮助和指导。

使用堆栈跟踪更新

Stack Trace:
   at Microsoft.Extensions.Logging.LoggerExtensions.Log(ILogger logger, LogLevel logLevel, EventId eventId, Exception exception, String message, Object[] args)
   at Microsoft.Extensions.Logging.LoggerExtensions.LogError(ILogger logger, Exception exception, String message, Object[] args)
   at Project.Controllers.OrderController.CustomerOrders(String customerId) in C:\projects\Project\Controllers\OrderController.cs:line 34
   at Tests.OrderControllerTest.AllOrdersForCustomer() in C:\projects\UnitTests\Project.Service.Tests\OrderControllerTest.cs:line 74

我目前拥有的:

OrderControllerTest.cs:

using System;
using System.Collections.Generic;
using NUnit.Framework;
using Project.Models;
using Project.Controllers;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;

namespace Tests
{
  [TestFixture]
  public class OrderControllerTest
  {
      ILogger<OrderController> _logger;

      public OrderControllerTest()
      {

      }

      [Test]
      public void AllOrdersForCustomer()
      {
        // Arrange
        var controller  = new OrderController(_logger);
        var expectedResult = new List<Order>();
        var oneOrder = new Order()
        {
            orderId = 228, 
            product= "Jeans",
            status = "Ready for shipping",
            price= 20$
        };

        var twoOrder = new Order()
        {
            caseId = 512, 
            creditorName = "Basketball",
            status = "Shipped",
            totalOpenBalance = 30$
        };
        expectedResult.Add(oneOrder);
        expectedResult.Add(twoOrder);

        // Act
        var actionResult = controller.CustomerOrders("1243");
        var result = (List<Order>)actionResult;

        // Assert
        for (var i = 0; i < result.Count; i++)
        {               
          CollectionAssert.AreEqual(expectedResult, result);
        }
    }
}

OrderController.cs:

using System;
using System.Collections.Generic;
using Project.Models;
using Project.Repositories;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;


namespace Project.Controllers
{
  public class OrderController : Controller
  {
    ILogger<OrderController> _logger;

    public OrderController(ILogger<OrderController> logger)
    {
        _logger = logger;
    }

    [HttpGet("customers/{customerId}/orders")]
    public List<Order> CustomerOrders(string customerId)
    {
        try
        {
            return OrderRepository.AllOrders(customerId);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Cant retrieve no orders.");
            return null;
        }
    }
  }
}

 ILogger<OrderController> _logger;

 public OrderControllerTest()
 {
    _logger = new Mock<ILogger<OrderController>>().Object;  
 }

OrderRepository.cs:

    public static List<Order> AllOrders(string customerId)
    {
        var orderlist = new List<Order>();


        if (Order!=null && Order.Count>0)
        {
            if (Order.TryGetValue(customerId, out orderlist))
                return orderlist;
        }
        return FromDB(customerId);

    }

在 "OrderControllerTest" class 的构造函数中,您需要创建 ILogger 接口的模拟。 Logger 是您的 OrderController 的依赖项,您不想在控制器的单元测试中测试它的功能。

有很多好的模拟框架。我更喜欢 Moq 但还有很多其他的。然后您需要模拟您的 OrderController 正在使用的方法。

最小起订量示例:

using ...
using Moq;

namespace Tests
{
  [TestFixture]
  public class OrderControllerTest
  {
    public OrderControllerTest()
    {
      var mockLogger = new Mock<ILogger<OrderController>>();
      mockLogger.Setup( x => x.LogError( It.IsAny<Exception>(), It.IsAny<string>() );
      _logger = mockLogger.Object;
    }
  ...
  }
}

假设您已从 EL MOJO 获取输入,您需要在测试中使用 Moq 初始化 ILogger:

Mock<ILogger<OrderController>> _logger;

public OrderControllerTest()
{
    _logger = new Mock<ILogger<OrderController>>();
    _logger.Setup(m => m.LogError(It.IsAny<Exception>(), It.IsAny<string>()));
}

现在您应该使用以下内容初始化您的控制器:

var controller  = new OrderController(_logger.Object);