如何单元测试此方法的catch块?

Nin*_*ore 2 c# error-handling nunit rhino-mocks asp.net-mvc-3

我正在学习单元测试.如何使用NUnit和Rhino Mock对此方法进行单元测试?好吧,我已经测试了try块,并希望测试catch块代码覆盖率.

[HttpPost]
public ActionResult AppraisalOrderIsAcceptedByEmployee(int appraisalOrderId)
{
    try
    {
        this.appraisalOrderService.SubmitAppraisalOrder(appraisalOrderId);
    }
    catch (MessageLoneException ex)
    {
        // Display validation errors
        PersistErrors(ex);

        // Remains on the same view
        return RedirectToAction("VerifyOrderDetails", new { id = appraisalOrderId });
    }
    return GetLoginRedirectCurrentUser();
}
Run Code Online (Sandbox Code Playgroud)

Dar*_*rov 6

假设这appraisalOrderService是一个接口(在正确设计的应用程序中是一个安全的假设),你的控制器作为构造函数注入,你可以使用你最喜欢的模拟框架轻松地模拟它.例如,使用Rhino Mocks,您的测试可能如下所示:

[TestMethod]
public void AppraisalOrderIsAcceptedByEmployee_Should_Redirect_To_VerifyOrderDetails_Action_If_SubmitAppraisalOrder_Throws_A_MessageLoneException()
{
    // arrange
    var appraisalOrderId = 5;
    var orderServiceMock = MockRepository.GenerateMock<IOrderService>();
    orderServiceMock
        .Expect(x => x.SubmitAppraisalOrder(appraisalOrderId))
        .Throw(new MessageLoneException());
    var sut = new MyController(orderServiceMock);

    // act
    var actual = sut.AppraisalOrderIsAcceptedByEmployee(appraisalOrderId);

    // assert
    Assert.IsInstanceOfType(actual, typeof(RedirectToRouteResult));
    Assert.AreEqual("VerifyOrderDetails", result.RouteValues["action"]);
    Assert.AreEqual(appraisalOrderId, result.RouteValues["id"]);
}
Run Code Online (Sandbox Code Playgroud)

您尚未显示PersistErrors方法是什么以及它的行为方式,因此很难说出正确的测试方法.如果此方法正在使用它们,您可能需要模拟其他内容.鉴于你提出的评论,我认为你在某种程度上添加错误ModelState使用AddModelErrorMethod.如果是这种情况,您可以在测试的断言阶段验证它:

Assert.IsFalse(sut.ModelState.IsValid);
Run Code Online (Sandbox Code Playgroud)

如果您知道存储错误的密钥:

Assert.AreEqual(
    "some expected message",
    sut.ModelState["someKey"].Errors.Single().ErrorMessage
);
Run Code Online (Sandbox Code Playgroud)