简体   繁体   English

单元测试使用 QueryString 的控制器

[英]UnitTesting a controller that used QueryString

Im trying with this TestMethod我正在尝试使用此 TestMethod

[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);

To test the following controller.测试以下控制器。 Before i use QueryString i had a HttpGet with parameters and the test was succesful:在我使用 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));
        }

Im getting null reference exception, im not sure why.我收到空引用异常,我不知道为什么。 Also im not sure if i somehow must pass to the controler the terms object.我也不确定我是否必须以某种方式将条款对象传递给控制器​​。 With parameters i was passing the terms from parameters.使用参数,我正在传递参数中的术语。

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

I don't think the null check (as suggested in your answer) is the right approach here.我不认为空检查(如您的答案中所建议)是正确的方法。 While I wouldn't normally argue against that, there would be no way that the Request object could be null in a production environment.虽然我通常不会反对这一点,但在生产环境中 Request 对象不可能为空。 In fact, by adding the null check, you are allowing the test to branch such that it is not really testing the functionality of the method as used in production.事实上,通过添加空检查,您允许测试分支,这样它就不会真正测试生产中使用的方法的功能。

The real solution would be to mock the Request so that you can provide the query string parameters that are expected by the Controller method.真正的解决方案是模拟请求,以便您可以提供 Controller 方法所需的查询字符串参数。 See this answer for some advice on that.有关方面的一些建议,请参阅此答案

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM