单元测试使用 QueryString 的控制器

UnitTesting a controller that used QueryString

我正在尝试使用此测试方法

[TestMethod]
        [Description("Checks if the SearchResults Controller is generating any data from the Report")]
        public async Task GetAllOldCustomersContainingTerm_FromSearchResultsControllerTest()
        {
            // Create mock configuration files for every class
            DalConfig config = new DalConfig()
            {
                ConnectionString = "Trusted_Connection=True;database=AdventureWorks2017;Server=localhost\MSSQL2017",
            };

            // Create mock options, PrintService and logger
            var mockOptions = new Mock<IOptions<DalConfig>>();
            mockOptions.Setup(op => op.Value).Returns(config);
            var searchResultFunctions = new SearchResultFunctions();
            var logger = new Logger<SearchResultsController>(new LoggerFactory());

            var mockSearchResultServices = new Mock<SearchResultService>().As<ISearchResultService>();
            mockSearchResultServices.CallBase = true;

            // Terms to test. In MockDatabase, John exist on FirstName and 12345 on PostalCode
            var terms = new SearchTerms
            {
                FirstName = "John",
                PostalCode = "123456"
            };

            mockSearchResultServices.Setup(x => x.GetAllOldCustomersContainingTermAsync(config, terms))
                .ReturnsAsync(new WebApiMockDatabaseRecordsProvider().GetAllMockOldCustomersDtos());

            // Create mock controller
            var testController = new SearchResultsController(logger, mockSearchResultServices.Object, searchResultFunctions, mockOptions.Object);

            var result = await testController.GetAllOldCustomersContainingTermAsync() as OkObjectResult;

            // Check if data is being returned from the Controller
            Assert.IsTrue(result.Value != null);

测试以下控制器。 在我使用 QueryString 之前,我有一个带参数的 HttpGet 并且测试成功:

[ApiController]
    [Route("[controller]")]
    public class SearchResultsController : ControllerBase
    {
        readonly ILogger<SearchResultsController> _logger;
        ISearchResultService ResultService;
        ISearchResultFunctions ResultFunctions;
        DalConfig DalConfig;
        public SearchResultsController(ILogger<SearchResultsController> logger
            , ISearchResultService resultService, ISearchResultFunctions resultFunctions, IOptions<DalConfig> settings)
        {
            DalConfig = settings.Value;
            ResultService = resultService;
            ResultFunctions = resultFunctions;
            _logger = logger;
        }
        /// <summary>
        /// Returns all customers with values that matches in any of the terms
        /// Searches all the customer fields except BusinessEntityId and BirthDate
        /// </summary>
        /// <param name="terms">a list of string terms, seperated by space</param>
        /// <returns></returns>
        [HttpGet("FindOldCustomers/{terms?}")]
        public async Task<IActionResult> GetAllOldCustomersContainingTermAsync()
        {
            //if (terms == null)
                var terms = new SearchTerms()
                {
                    FirstName = Request.Query["FirstName"],
                    LastName = Request.Query["LastName"],
                    EmailAddress = Request.Query["EmailAddress"],
                    Gender = Request.Query["Gender"],
                    AddressLine1 = Request.Query["AddressLine1"],
                    AddressLine2 = Request.Query["AddressLine2"],
                    City = Request.Query["City"],
                    JobTitle = Request.Query["JobTitle"],
                    PhoneNumber = Request.Query["PhoneNumber"],
                    PostalCode = Request.Query["PostalCode"],
                };
            var config = new DalConfig()
            {
                ConnectionString = DalConfig.ConnectionString,
            };
            var task = await ResultService.GetAllOldCustomersContainingTermAsync(config, terms);
            if (task.Count == 0)
                return NotFound();
            return Ok(ResultFunctions.ConvertToJSON(task));
        }

我收到空引用异常,我不确定为什么。 我也不确定我是否必须以某种方式将条款对象传递给控制器​​。使用参数,我正在传递参数中的术语。

我在控制器中添加了一个检查请求是否为空并且现在测试通过

我认为 null 检查(如您的回答中所建议的)在这里不是正确的方法。虽然我通常不会反对这一点,但 Request 对象在生产环境中不可能为空。事实上,通过添加 null 检查,您允许测试分支,这样它就不会真正测试生产中使用的方法的功能。

真正的解决方案是模拟 Request,以便您可以提供 Controller 方法所需的查询字符串参数。有关这方面的一些建议,请参阅 this answer