2

単体テストを学んでいます。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();
}
4

2 に答える 2

6

コントローラーがコンストラクター インジェクションとして受け取るインターフェイス (適切に設計されたアプリケーションでは安全な想定appraisalOrderServiceです) であると仮定すると、お気に入りのモック フレームワークで簡単にモックできます。たとえば、Rhino モックを使用すると、テストは次のようになります。

[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"]);
}

メソッドが何であるか、PersistErrorsどのように動作するかを示していないため、テストする適切な方法を伝えるのは困難です. このメソッドがそれらを使用している場合は、追加のものをモックする必要があるかもしれません。あなたが上に置いたコメントを考えると、どういうわけか、ModelStateを使用してにエラーを追加していると思いますAddModelErrorMethod。この場合、テストのアサーション フェーズで検証できます。

Assert.IsFalse(sut.ModelState.IsValid);

エラーを保存したキーがわかっている場合:

Assert.AreEqual(
    "some expected message",
    sut.ModelState["someKey"].Errors.Single().ErrorMessage
);
于 2013-01-17T13:58:41.643 に答える
0

おそらくPersistErrors()独立してテストできます。

AndRedirectToActionはフレームワーク メソッドです。フレームワークをテストする必要はありません。

コード カバレッジのためだけにブロックの内容をテストするのはcatch、少し行き過ぎのように思えます。ロジックは関係ありません。

appraisalOrderService.SubmitApraisalOrder()必要に応じて a をスローするかどうかをテストするMessageLoneException必要があります。

80/20 ルールを思い出してください。フレームワークのカバレッジをテストすることはあまり効率的ではなく、開発者としての貴重な時間を無駄にします。

このメソッドでまだ catch ブロックをテストしたい場合は、サービスを偽造してFakeAppraisalOrderService.SubmitApraisalOrder()MessageLoneException.

それでも、実際のロジックのテストに時間を費やすことをお勧めします。100% のカバレッジは理想的な目標であり、規則ではありません。

于 2013-01-17T14:19:34.687 に答える