Moq设置返回null

时间:2016-03-11 03:31:58

标签: c# asp.net entity-framework asp.net-web-api moq

所以,我开始在我正在研究的Web Api项目上学习UniTesting工具。发生了什么事情,当我设置一个模拟调用时,这个返回null而不是我告诉返回的值。我不知道为什么一个类似的设置工作,但这个没有。

这是我的测试类

namespace API.Tests.Web
{
    [TestClass]
    public class MaterialsControllerTest
    {
        private MaterialsController controller;
        private Mock<IRTWRepository> repository;
        private Mock<IModelFactory> factory;
        private Mock<IRTWAPIIdentityService> identityService;
        List<MaterialAccepted> materials;
        MaterialAccepted material;      

        [TestInitialize]
        public void Initialize()
        {
            repository = new Mock<IRTWRepository>();
            factory = new Mock<IModelFactory>();          
            identityService = new Mock<IRTWAPIIdentityService>();
            controller = new MaterialsController(repository.Object);
            material = new MaterialAccepted()
            {
                business = true,
                businessService = EnumRecycleCenterService.Dropoff,
                residential = false,
                residentialService = EnumRecycleCenterService.Pickup,
                note = "this a note",
                Category = new Category()
                {
                    name = "Books"
                }
            };

            materials = new List<MaterialAccepted>()
                {
                    new MaterialAccepted() { business=true,businessService=EnumRecycleCenterService.Dropoff,residential=false,residentialService=EnumRecycleCenterService.Pickup,note="this a note"},
                    new MaterialAccepted() { business=false,businessService=EnumRecycleCenterService.Dropoff,residential=true,residentialService=EnumRecycleCenterService.Pickup,note="this a note"},
                };
        }    

        [TestMethod]        
        public void Post_ShouldReturnBadRequestWhenMaterialAcceptedModelValidationFails()
        {            
            //arrange
            repository.Setup(r => r.RecycleCenterRepository.Get(3)).Returns(() => new RecycleCenter());
            controller.ModelState.AddModelError("error", "unit test error");
            //act

            var actionResult = controller.Post(2, new MaterialAcceptedModel());

            Assert.IsInstanceOfType(actionResult, typeof(BadRequestResult));
        }                                        
    }
}

以下是我正在尝试测试的控制器中的操作

[HttpPost]
        [Route("api/recyclecenters/{rcid}/materials/")]
        public IHttpActionResult Post(int rcid, [FromBody]MaterialAcceptedModel model)
        {
            try
            {
                if (model != null)
                {
                    var recycleCenter = TheRepository.RecycleCenterRepository.Get(rcid);

                    if (recycleCenter == null)
                        return NotFound();

                    if (!ModelState.IsValid)
                        return BadRequest(ModelState);

                    var entity = TheModelFactory.Parse(model);

                    if (entity == null) return BadRequest("Could not read material accepted in body");

                    if (TheRepository.MaterialAcceptedRepository.Get(recycleCenter.RecycleCenterId, entity.Category.name) != null)
                        return Conflict();

                    recycleCenter.Materials.Add(entity);

                    if (TheRepository.SaveAll())
                    {
                        string locationHeader = Url.Link("Materials", new { rcid = rcid, name = model.category.ToLower() });
                        return Created<MaterialAcceptedModel>(locationHeader, TheModelFactory.Create(entity));
                    }
                    return BadRequest("Could not save to the database");
                }
                return BadRequest();
            }
            catch (Exception ex)
            {
                return BadRequest(ex.Message);
            }    
        }

如果我运行此测试,它将失败,因为它返回一个实例类型的NotFoundResult而不是BadRequestResult,这是因为测试方法在此行停止

if (recycleCenter == null)
    return NotFound();

但是这个测试假设停在这条线上

 if (!ModelState.IsValid)
      return BadRequest(ModelState);

任何想法为什么这个

 repository.Setup(r => r.RecycleCenterRepository.Get(3)).Returns(() => new RecycleCenter());

在返回新的RecycleCenter

时返回null

1 个答案:

答案 0 :(得分:2)

您似乎正在为rcid = 3设置存储库模拟,并使用rcid = 2调用控制器中的存储库。

    public enum AlphaNumber
    { 
        A=2, B=2, C=2, D=3, E=3, F=3, G=4, H=4, I=4, J=5, K=5, L=5, 
        M=6, N=6, O=6, P=7, Q=7, R=7, S=8, T=8, U=8, V=9, W=9, X=9, Y=9, Z=9
    }

    public static class PhoneNumber
    {
        public static char ParseInput(char input)
        {
            if (input == '-' || char.IsDigit(input))
            {
                return input;
            }

            if (char.IsLetter(input))
            {
                var num = (AlphaNumber)(Enum.Parse(typeof(AlphaNumber), (char.IsLower(input) ? char.ToUpperInvariant(input) : input).ToString()));
                return ((int)num).ToString()[0];
            }

            return '\0';
        }
    }

尝试使用rcid = 3

调用它
        //arrange
        repository.Setup(r => r.RecycleCenterRepository.Get(3)).Returns(() => new RecycleCenter());
        controller.ModelState.AddModelError("error", "unit test error");
        //act

        var actionResult = controller.Post(2, new MaterialAcceptedModel());

或将Moq设置参数更改为 var actionResult = controller.Post(3, new MaterialAcceptedModel());