2016-06-08 107 views
1

我正在爲已編寫的代碼編寫一些單元測試。我遇到了一個令人驚訝的情況,我沒有遇到過。嘲笑服務渠道

總之,我需要測試一個Controller,它通過DI接受服務依賴關係,並在Index操作中調用該服務的方法以返回視圖的數據。

我的問題是,我似乎無法嘲笑服務依賴。我嘗試了一下搜索,但找不到直接處理我的問題(或我缺乏理解)的任何內容。

下面是控制器的一個示例:

public partial class SomeController : Controller 
{ 
    private readonly IServiceChannel<ISomeService> _someChannel; 

    public SomeController(IServiceChannel<ISomeService> someChannel) 
    { 
     _someChannel= someChannel; 
    } 

    public virtual ActionResult Index() 
    { 
     var response = _someChannel.Fetch(someService => someService .GetSomeData(
      new GetSomeDataRequest 
      { 
       Id= StaticData.Id, 
       All = true 
      } 
     )); 

     var model = new IndexViewModel 
     { 
      AllData= response.AllData 
     }; 

     return View(model); 
    } 
} 

正如你可以看到,DI噴射其中有一個「獲取」方法IServiceChannel的一個實例。然後,該方法可讓您訪問ISomeService,然後您可以使用必要的參數調用接口上的任何方法。

我嘗試使用下面的邏輯來寫解決這個測試:

[TestFixture] 
public class SomeControllerTests 
{ 
    private IServiceChannel<ISomeService> _someChannel; 
    [SetUp] 
    public void Setup() 
    { 
     var someChannelMoc = new Mock<IServiceChannel<ISomeService>>(); 
     someChannelMoc.Setup(
      i => i.Fetch(service => service.GetSomeData(It.IsAny<GetSomeDataRequest>()))) 
      .Returns(new GetSomeDataResponse()); 

     _someChannel= someChannelMoc.Object; 
    } 

    [Test] 
    public void IndexTest() 
    { 
     var controller = new SomeController(_someChannel); 
     var result = controller.Index(); 
     Assert.IsNotNull(result); 
    } 
} 

這一切都建立好了,但是當測試運行我看到下列錯誤:

SetUp : System.NotSupportedException : Unsupported expression: service => service.GetSomeData(IsAny()) at Moq.MatcherFactory.CreateMatcher(Expression expression, Boolean isParams) at Moq.MethodCall..ctor(Mock mock, Condition condition, Expression originalExpression, MethodInfo method, Expression[] arguments) at Moq.MethodCallReturn..ctor(Mock mock, Condition condition, Expression originalExpression, MethodInfo method, Expression[] arguments) at Moq.MethodCallReturn 2..ctor(Mock mock, Condition condition, Expression originalExpression, MethodInfo method, Expression[] arguments) at Moq.Mock.<>c__DisplayClass1c 2.b__1b() at Moq.PexProtector.Invoke[T](Func 1 function) at Moq.Mock.Setup[T,TResult](Mock 1 mock, Expression 1 expression, Condition condition) at Moq.Mock 1.Setup[TResult](Expression`1 expression) at MyProj.Tests.Controllers.SomeControllerTests.Setup() in path location

任何幫助將非常感謝!

回答

1

那麼,經過一番努力,我認爲我想通了。我需要的功能參數在我IServiceChannel實現匹配:

public TResult Fetch<TResult>(Func<T, TResult> block) 
{ ... } 

所以現在我的測試設置改成這個樣子:

var someChannelMoc = new Mock<IServiceChannel<ISomeService>>(); 
      someChannelMoc.Setup(i => i.Fetch(It.IsAny<Func<ISomeService,GetSomeDataResponse>>())) 
       .Returns(()=>new GetSomeDataResponse{AllData= new List<Data>()}); 

      _someChannel = someChannelMoc.Object; 

爲了能有更好的緣故,我要抱將此標記爲回答以查看是否有更好的結果出現,因爲我無法指定函數的輸入參數。這對我來說不是一個問題,但它可能適用於未來的某個人。