Yag*_*Yag 2 asp.net-mvc unit-testing moq builder-pattern
我正在使用构建器模式为控制器生成视图模型,当我尝试对控制器进行单元测试时,我发现自己无法这样做.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);
}
}
Run Code Online (Sandbox Code Playgroud)
我试图模拟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);
}
Run Code Online (Sandbox Code Playgroud)
(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>)
Run Code Online (Sandbox Code Playgroud)
(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>)
Run Code Online (Sandbox Code Playgroud)
(3)不抛出编译时错误而是运行时错误:
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()
Run Code Online (Sandbox Code Playgroud)
任何帮助将不胜感激.应该对这种方法进行单元测试是不是很难,是吗?
您可以在下面看到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;
}
}
Run Code Online (Sandbox Code Playgroud)
最后,IOutletViewModelBuilder接口
public interface IOutletViewModelBuilder
{
OutletViewModel Build();
OutletViewModelBuilder WithOutlet(int outletId);
OutletViewModelBuilder WithCountryList();
}
Run Code Online (Sandbox Code Playgroud)
看起来主要的问题是你的WithOutlet和WithCountryList方法返回一个具体的OutletViewModelBuilder,而不是返回一个IOutletViewModelBuilder.我想你需要这样的东西:
public interface IOutletViewModelBuilder
{
OutletViewModel Build();
IOutletViewModelBuilder WithOutlet(int outletId);
IOutletViewModelBuilder WithCountryList();
}
Run Code Online (Sandbox Code Playgroud)
然后你的嘲笑:
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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3017 次 |
| 最近记录: |