2011-06-27 12 views
2

ビルダーパターンを使用してコントローラ用のビューモデルを生成しています。コントローラのユニットテストをしようとしていたときに、自分自身がそうすることができませんでした。 Moqは文句を言う。Moqを使ったユニットテストビルダーパターン

Moqの制限か自分の制限と無知かどうかは不明です。

これは私のコントローラは次のようになります。

public class OutletController : Controller 
{ 
    private readonly IOutletViewModelBuilder _builder; 

    public OutletController(IOutletViewModelBuilder builder) 
    { 
     this._builder = builder; 
    } 


    public ActionResult Edit(int id) 
    { 
     OutletViewModel viewModel = this._builder.WithOutlet(id).WithCountryList().Build(); 

     return View(viewModel); 
    } 
} 

私はIOutletViewModelBuilderオブジェクトを模擬しようとしていますが、これは私が得るものです:

[Test] 
public void DummyTest() 
{ 
    Mock<IOutletViewModelBuilder> mockBuilder = new Mock<IOutletViewModelBuilder>(); 
    // (1) // mockBuilder.Setup(m => m.WithOutlet(It.IsAny<int>())).Returns(mockBuilder.Object); 
    // (2) //mockBuilder.Setup(m => m.WithOutlet(It.IsAny<int>())).Returns(mockBuilder); 

    // (3) // mockBuilder.Setup(m => m.WithOutlet(It.IsAny<int>()).WithCountryList().Build()).Returns(new OutletViewModel()); 

    OutletController controller = new OutletController(mockBuilder.Object); 
    ActionResult result = controller.Edit(1); 

    Assert.IsTrue(true); 
} 

(1)は私を与えます次のエラーの強調表示(mockBuilder.Object)

メソッドを解決できません'戻り値(ViewModelBuilders.Builders.IOutletViewModelBuilder)'、候補者は次のとおりです。

Moq.Language.Flow.IReturnsResult<ViewModelBuilders.Builders.IOutletViewModelBuilder> Returns(System.Func<ViewModelBuilders.Builder.IOutletViewModelBuilder>) (in interface IReturns<IOutletViewModelBuilder,OutletViewModelBuilder>) 
Moq.Language.Flow.IReturnsResult<ViewModelBuilders.Builders.IOutletViewModelBuilder> Returns(ViewModelBuilders.Builders.OutletViewModelBuilder) (in interface IReturns<IOutletViewModelBuilder,OutletModelBuilder>) 

(2)は、次のエラーがスローされます。

は、メソッド '戻り値(Moq.Mock)' を解決できない、候補者は、次のとおりです。

Moq.Language.Flow.IReturnsResult<ViewModelBuilders.Builders.IOutletViewModelBuilder> Returns(System.Func<ViewModelBuilders.Builders.OutletViewModelBuilder>) (in interface IReturns<IOutletViewModelBuilder,OutletViewModelBuilder>) 
Moq.Language.Flow.IReturnsResult<ViewModelBuilders.Builders.IOutletViewModelBuilder> Returns(ViewModelBuilders.Builders.OutletViewModelBuilder) (in interface IReturns<IOutletViewModelBuilder,OutletViewModelBuilder>) 

(3)は、コンパイル時にエラーが、ランタイム1をスローしません:

System.NotSupportedException : Invalid setup on a non-virtual (overridable in VB) member: m => m.WithOutlet(It.IsAny<Int32>()).WithCountryList().Build() 
at Moq.Mock.ThrowIfCantOverride(Expression setup, MethodInfo method) 
at Moq.Mock.<>c__DisplayClass1c`2.<Setup>b__1b() 
at Moq.Mock.Setup(Mock mock, Expression`1 expression, Func`1 condition) 
at ViewModelBuilderTests.OutletControllerTest.DummyTest() 

ご協力いただければ幸いです。これは、このメソッドを単体テストするのは難しいことではありませんか?

実装を確認する必要がある場合は、Builderオブジェクトが表示されます。最後に

public class OutletViewModelBuilder 
{ 
    private readonly IRepository _repository; 
    private OutletViewModel _viewModel; 

    public OutletViewModelBuilder(IRepository repository) 
    { 
     this._repository = repository; 
     this._viewModel = new OutletViewModel(); 
    } 

    public OutletViewModel Build() 
    { 
     return this._viewModel; 
    } 

    public OutletViewModelBuilder WithOutlet(int outletId) 
    { 
     this._viewModel.Outlet = this._repository.GetOutletById(outletId); 

     return this; 
    } 

    public OutletViewModelBuilder WithCountryList() 
    { 
     this._viewModel.CountryList = this._repository.GetCountryList(); 

     return this; 
    } 
} 

IOutletViewModelBuilderインタフェース

public interface IOutletViewModelBuilder 
{ 
    OutletViewModel Build(); 

    OutletViewModelBuilder WithOutlet(int outletId); 

    OutletViewModelBuilder WithCountryList(); 
} 
+0

:その後、

public interface IOutletViewModelBuilder { OutletViewModel Build(); IOutletViewModelBuilder WithOutlet(int outletId); IOutletViewModelBuilder WithCountryList(); } 

あなたのモック:私はあなたがこのようなものが必要だろうと思います。 OutletViewModelBuilderオブジェクトをどのようにMoqできますか? mockingフレームワークを変更する必要がありますか? – Yag

+0

あなたはモックしたい 'IOutletViewModelBuilder'のコードを投稿できますか? – froeschli

答えて

5

主な問題は、あなたのWithOutletとWithCountryList方法は、具体的なOutletViewModelBuilderを返す代わりにIOutletViewModelBuilderに戻ってきているということであるように見えます。質問が明確でない場合は

var myViewModel = TheOutletViewModelForTesting(); 
var mockBuilder = new Mock<IOutletViewModelBuilder>(); 

mockBuilder.Setup(m => m.WithOutlet(It.IsAny<int>())).Returns(mockBuilder.Object); 
mockBuilder.Setup(m => m.WithCountryList()).Returns(mockBuilder.Object); 
mockBuilder.Setup(m => m.Build()).Returns(myViewModel); 

// rest of your test that validates that myViewModel is passed correctly to your view 
+0

それだけです!ありがとうブライアン、それはほとんど恥ずかしいです。本当に感謝!だから問題は私だった。 :-) – Yag

関連する問題