【问题标题】:Asp.net MVC Test of Create action method with NUnit and Nsubstitute always fails使用 NUnit 和 Nsubstitute 创建操作方法的 Asp.net MVC 测试总是失败
【发布时间】:2012-05-24 02:57:39
【问题描述】:

我有这个控制器:

[HttpPost]
        public  ActionResult Create(Company company)
        {

            // try to save the record
            if (ModelState.IsValid)
            {

                // create the command
                var command = new CreateOrUpdateCompanyCommand
                {
                    CompanyId = company.CompanyId,
                    Code = company.Code,
                    Name = company.Name
                };

                // check for errors
                IEnumerable<ValidationResult> errors = _commandBus.Validate(command);

                ModelState.AddModelErrors(errors);

                if (ModelState.IsValid)
                {
                    var result = _commandBus.Submit(command);
                    if (result.Success) 
                        return RedirectToAction("Index");
                }

            }

            // if fail
            return View("Create", company);

        }

我有这个 NUnit 测试:

[Test]
        public void Create()
        {

            const string expectedRouteName = "Index";

            // Mock the arguments
            var mockRepository = Substitute.For<ICompanyRepository>();
            var mockProcessor = Substitute.For<ICommandBus>();

            // Arrange
            var controller = new CompanyController(mockProcessor, mockRepository);

            // Act
            var company = new Company
            {
                Code = "XXXXXXX",
                CompanyId = 1,
                Name = "Sample company"
            };

            var result = controller.Create(company) as RedirectToRouteResult;

            // Assert
            Assert.IsNotNull(result, "Should return a ViewResult");
            Assert.AreEqual(expectedRouteName, result.RouteValues["action"], 
                "View name should have been '{0}'", expectedRouteName);

        }

这是模型:

公开课公司 {

[Key]
public int CompanyId { get; set; }

[Required(ErrorMessage = "* (xxxx)")]
[MaxLength(7)]
[RegularExpression("^([A-Z0-9]{7})$", ErrorMessage = "xxx")]
[Display(Name = "Code")]
public string Code { get; set; }

[Required(ErrorMessage = "*")]
[MaxLength(40)]
[Display(Name = "Name")]
public string Name { get; set; }

}

当我运行测试时,这个函数总是返回 false:var result = _commandBus.Submit(command); 并且测试失败。

我不知道如何测试它?我应该模拟 _commandBus 并将其设置为返回 true 吗?我尝试过这种方式但没有成功:

        var mockCommand = Substitute.For<ICommand>();

        mockProcessor.Submit(mockCommand).Success.Returns(true);

为了创建这个项目,我从http://efmvc.codeplex.com/得到了灵感

对我有什么建议吗?谢谢。

【问题讨论】:

  • 在我看来,您不应该在模拟设置示例代码中创建命令的模拟。而只是模拟公共汽车。
  • 我试过了,但没用,所以我删除了它...

标签: unit-testing mocking nunit asp.net-mvc-4 nsubstitute


【解决方案1】:

您传递给mockProcessor.Submit(mockCommand).Success.Returns(true) 的命令必须与被测代码传递的命令相同。当方法更新它自己的命令时,这种情况永远不会发生。

最简单的解决方法是在设置替代时匹配任何命令:

var result = CreateSuccessfulResult(); // <-- fill this in as appropriate
mockProcessor.Submit(null).ReturnsForAnyArgs(result);

我认为根据您的原始测试在内联结果中设置Success 字段应该也可以工作,但我发现指定所需的结果更清楚一些。

您可以通过匹配预期的命令类型来稍微改进一下:

mockProcessor.Submit(Arg.Any<CreateOrUpdateCompanyCommand>()).Returns(result);

如果您想测试,也可以检查通过的命令:

mockProcessor
    .Submit(Arg.Is<CreateOrUpdateCompanyCommand>(x => x.CompanyId = ...))
    .Returns(result);

可以使用类似的方法来检查Validate 调用。

NSubstitute docs 中有更多信息。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-03-28
    • 1970-01-01
    • 2019-04-17
    • 2022-12-09
    • 2018-10-20
    • 1970-01-01
    • 2012-05-15
    • 1970-01-01
    相关资源
    最近更新 更多