单元测试WebApi POST请求的正确方法是什么?

时间:2016-12-15 11:57:49

标签: unit-testing asp.net-web-api moq

通常我的所有测试都运行良好,除了测试POST请求之外。它总是返回BadRequest。我不知道到底出了什么问题,因为它不会在下面触发等级(例如服务层和数据层) 这是测试方法:

[TestMethod]
        public async Task AddTourObject()
        {
            // Упорядочение
            var mockService = new Mock<ITourObjectService>(MockBehavior.Default);
            var viewmodel = new TourObjectViewModel
            {
                TypeId = 10,
                Name = "Деревья гнулись",
                Address = "f yjxr",
                Latitude = 120.22,
                Longitude = 220.34,
                CountryId = 1,
                RegionId = 2,
                CityId = 1,
                Rating = 2,
                InternalRating = 2,
                CheckInTime = "12:00",
                CheckOutTime = "12:00",
                HowToGet = "sss",
                Web = "web",
                Email = "аааааа"
            };
            mockService.Setup(x => x.Add(It.IsAny<TourObjectDTO>())).ReturnsAsync(new ActionAnswer { });
            var controller = new TourObjectController(mockService.Object);
            // Действие
            var result = await controller.Post(viewmodel);
            // Утверждение
            Assert.IsNotNull(result);
            Assert.IsInstanceOfType(result, typeof(OkNegotiatedContentResult<string>));
            Assert.IsTrue(result.ToString().Contains("успешно"));
        }

测试方法:

public async Task<IHttpActionResult> Post(TourObjectViewModel viewmodel)
        {
            var answer = new ActionAnswer();
            try
            {
                var dto = new TourObjectDTO
                {
                    TypeId = viewmodel.TypeId,
                    Name = viewmodel.Name,
                    Address = viewmodel.Address,
                    Latitude = viewmodel.Latitude,
                    Longitude = viewmodel.Longitude,
                    CountryId = viewmodel.CountryId,
                    RegionId = viewmodel.RegionId,
                    CityId = viewmodel.CityId.Value,
                    Rating = viewmodel.Rating,
                    InternalRating = viewmodel.InternalRating,
                    CheckInTime = viewmodel.CheckInTime,
                    CheckOutTime = viewmodel.CheckOutTime,
                    HowToGet = viewmodel.HowToGet,
                    Web = viewmodel.Web,
                    Email = viewmodel.Email
                };
                answer = await _tos.Add(dto);
                return answer.IsSuccess == false ? (IHttpActionResult) BadRequest(answer.ToString()) : Ok(answer.ToString());
            }
            catch (Exception ex)
            {
                Log.ErrorFormat("Method:{0} <br/> Error: {1}", System.Reflection.MethodBase.GetCurrentMethod().Name, ex);
                return BadRequest(answer.ToString());              
            }
        }
  1. 我是否正确设置了此测试?
  2. 这是我应该测试的吗?

1 个答案:

答案 0 :(得分:1)

问题在于您的设置。对于每个提供的输入,您的服务设置将返回空ActionAnswer

mockService.Setup(x => x.Add(It.IsAny<TourObjectDTO>())).ReturnsAsync(new ActionAnswer{})

这意味着只提供返回空对象的服务。模拟的想法是尝试模拟程序中的不同行为和不同路径。因此,您可以测试以下方案:

1)如果服务返回带有IsSuccess == false的ActionAnswer,该怎么办? mockService.Setup(x => x.Add(It.IsAny<TourObjectDTO>())).ReturnsAsync(new ActionAnswer{ IsSuccess = false })

2)如果服务返回带有IsSuccess == true的ActionAnswer,该怎么办? mockService.Setup(x => x.Add(It.IsAny<TourObjectDTO>())).ReturnsAsync(new ActionAnswer{ IsSuccess = true })

您可以选择很多路径,但想法是找到关键路径并对其进行测试。