2016-11-24 5 views
2

controllerContextをパラメータとして使用して、3番目のパートライブラリ "Rotativa"に基づいてpdfドキュメントを生成するアクションをコントローラでテストします。ここ
は、アクション(機能)の実装です:ユニットテスト用のControllerContextでDisplayModeをモックする方法c#

public ActionResult DetailsPrint(int? id) 
{ 
    var a = new ViewAsPdf(); 
    a.ViewName = "../Ops/_2A1/Details"; 
    a.Model =UnitOfWork._2A1s.Get(id.Value); 
    var pdfBytes = a.BuildPdf(ControllerContext); 

    // return ActionResult 
    MemoryStream ms = new MemoryStream(pdfBytes); 
    return new FileStreamResult(ms, "application/pdf"); 

} 

そして、ここでは、私はユニットテストを取得しようとしている方法です動作します。

  • コンストラクタ

    public _2A1ControllerTest() 
    { 
        _mockRepository = new Mock<I2A1Repository>(); 
        var mockUoW = new Mock<IUnitOfWork>(); 
        _mockHttpContext = new Mock<HttpContextBase>(); 
        _mockRequest = new Mock<HttpRequestBase>(); 
        _mockDisplayModeContext = new Mock<IDisplayMode>(); 
        mockUoW.SetupGet(u => u._2A1s).Returns(_mockRepository.Object); 
        _mockHttpContext.SetupGet(x => x.Request).Returns(_mockRequest.Object); 
        _controller = new _2A1Controller(mockUoW.Object); 
        _controller.MockCurrentUser("test.admin"); 
        _controller.ControllerContext = new ControllerContext(_mockHttpContext.Object, new System.Web.Routing.RouteData(), _controller); 
    } 
    
  • 試験機能

    [TestMethod] 
    public void DetailsPrint_shouldPrint() 
    { 
        var result = _controller.DetailsPrint(1) as ActionResult; 
        result.Should().BeOfType<ActionResult>(); 
    } 
    

    私は怒鳴るfollwingエラーを取得し、テストを実行する場合: enter image description here

テスト名:DetailsPrint_shouldPrint テストフルネーム:OPSReviewTest._2A1ControllerTest.DetailsPrint_shouldPrint テストソース:C:\のinetpub \ wwwrootの\ OpsReview \ OPSReviewTest \コントローラがApi_2A1ControllerTest.cs \:ライン46 テスト結果:失敗 試験時間:0:04:39,3039007 結果のStackTrace:
System.Web.WebPages.DisplayでModeProvider.GetDisplayMode System.Web.Mvc.ControllerContext.get_DisplayMode() 結果メッセージにおいて(HttpContextBaseコンテキスト) : System.NullReferenceException:オブジェクト参照オブジェクトのインスタンスに設定されていないOPSReviewTest._2A1ControllerTest.DetailsPrint_shouldPrint例外が投げ 試験方法。

ありがとうございました。ありがとうございました。

+0

正確にこのメソッドでテストしようとしていますか? – Nkosi

答えて

1

あなたが所有していないユニットテストコードにしようとしていますか?

コントローラアクションフローを単独でテストすることを目標としていた場合は、第三者のPDF生成を抽象化してテスト容易性を向上させることをお勧めします(恥、[Bell tolls]、shame ...) 。

public interface IViewAsPdfWrapper { 
    string ViewName { get; set; } 
    object Model { get; set; } 
    byte[] BuildPdf(ControllerContext context); 
} 

public class ViewAsPdfWrapper : IViewAsPdfWrapper { 
    private readonly ViewAsPdf view; 
    public ViewAsPdfWrapper() { 
     view = new ViewAsPdf(); 
    } 
    public string ViewName { get; set; } 
    public object Model { get; set; } 
    public byte[] BuildPdf(ControllerContext context) { 
     view.ViewName = ViewName; 
     view.Model = Model; 
     return view.BuildPdf(context); 
    } 
} 

抽象化をコントローラに注入することで、必要に応じてリクエストアクションごとに使用できるようになりました。

public class _2A1Controller : Controller { 
    private readonly IUnitOfWork UnitOfWork; 
    private readonly IViewAsPdfWrapper viewAsPdf; 

    public _2A1Controller(IUnitOfWork uow, IViewAsPdfWrapper viewAsPdf) { 
     this.UnitOfWork = uow; 
     this.viewAsPdf = viewAsPdf; 
    } 

    public ActionResult DetailsPrint(int? id) { 
     var a = viewAsPdf; 
     a.ViewName = "../Ops/_2A1/Details"; 
     a.Model = UnitOfWork._2A1s.Get(id.Value); 
     var pdfBytes = a.BuildPdf(ControllerContext); 

     // return ActionResult 
     MemoryStream ms = new MemoryStream(pdfBytes); 
     return new FileStreamResult(ms, "application/pdf"); 
    } 

} 

そして今、ユニットテストは安全にFluentAssertionsの使用を想定すると、サードパーティの機能

public _2A1ControllerTest() {  
    _mockRepository = new Mock<I2A1Repository>(); 
    var mockUoW = new Mock<IUnitOfWork>(); 
    mockUoW.SetupGet(u => u._2A1s).Returns(_mockRepository.Object); 

    var mockViewAsPdf = new Mock<IViewAsPdfWrapper>(); 
    mockViewAsPdf.Setup(m => m.BuildPdf(It.IsAny<ControllerContext>())) 
     .Returns(() => new byte[0]); 

    _mockRequest = new Mock<HttpRequestBase>(); 
    _mockHttpContext = new Mock<HttpContextBase>(); 
    _mockHttpContext.SetupGet(x => x.Request).Returns(_mockRequest.Object); 

    _controller = new _2A1Controller(mockUoW.Object, mockViewAsPdf.Object); 
    _controller.MockCurrentUser("test.admin"); 
    _controller.ControllerContext = new ControllerContext(_mockHttpContext.Object, new System.Web.Routing.RouteData(), _controller); 

} 

を模擬することができ、試験方法は(しゃれが意図した:))

[TestMethod] 
public void DetailsPrint_shouldPrint() { 
    var result = _controller.DetailsPrint(1) as ActionResult; 
    result.Should() 
     .NotBeNull() 
     .And 
     .BeAssignableTo<ActionResult>(); 
} 
次のようになります。

最後に、インターフェイスとその実装を本番環境のDIコンテナに登録することを忘れないでください。

+0

まず、私を助けてくれてありがとう、多くの時間と検索を保存してくれてありがとう、本当に嬉しいです。 あなたは疑問に思っています。それは自分自身のコードであり、私の最初の体験を模擬し、3番目の部分ライブラリをシミュレートします。 あなたはその中の学者です。 –

+1

自分のコードを書いたとき、私は第三者のライブラリを参照していました。それは言うことであり、冗談として意味されていました:)。サードパーティのライブラリプロバイダは、リリース前にコードをテストしておく必要があります。だから、それを試そうとするのはあなたの時間の無駄です。それをあなたが持っている抽象的なものにラップすることによって、あなたはそれを模擬して少し柔軟性を持ってテストできるというコントロールを持っています。 – Nkosi

+0

ああ、すべてのアドバイスとお時間をいただきありがとうございます。 –

0

あなたはこのを追加ControllerContextDsiplayModeプロパティを割り当てるのを忘れ:

_controller.ControllerContext.DisplayMode=_mockDisplayModeContext.Object; 
+0

お返事ありがとう@esiprogrammerしかし、それは動作しませんでした –

+0

@ayyoubそれは動作しなかったことを意味しますか?まだ同じ行に同じ例外がありますか? – esiprogrammer

+0

ああ、私はまだ同じ例外を抱えています。私は結果がなくても昨日4時間過ごしました。そして誰もが同じ問題を抱えていることを期待してstackoverflowに入れました。あなたのインタラクティブ性に感謝します。 –

関連する問題