MOQ任务回调返回不支持的表达式上下文

时间:2016-06-08 20:42:50

标签: c# moq

我已经争吵了几个小时,甚至连另外两个同事,我们终于得到了编译器很满意的语法,但是MOQ看起来现在不开心了!!

代码来自一个非常大的项目,所以我只提供第一级抽象,否则这很可能是SO所见过的最长的帖子。

我将从我的单元测试开始:

[TestMethod]
public async Task GetPlan_BadPlanID()
{
   ...snip...

   //Create DataAccessTemplate at this point doesn't need anything special
   Mock<IDataAccessTemplate> dataAccessTemplate = new Mock<IDataAccessTemplate>();

   //This is the line that throws the exception   
   dataAccessTemplate
      .Setup(template => template.InvokeAsync<DefaultActionPlan>(context => Task.FromResult(new DefaultActionPlan())))
      .Returns(Task.FromResult(new DefaultActionPlan()));

     ...snip rest of test....
}

现在如果需要,我会展示所有被嘲笑的东西,但为了简洁起见,我将展示有问题的方法。

public class PlanDataProvider : BaseDomainServiceProvider, IPlanDataProvider
{
    protected IDataAccessTemplate Template { get; set; }


   public async Task<DefaultActionPlan> GetDefaultActionPlan(string referenceListId)
   {
      var objectId = GetObjectId(referenceListId);

      var defaultActionPlan = await Template.InvokeAsync(context => Task.FromResult(EntityStore.GetEntityById<DefaultActionPlan, ObjectId>
      (
         context.ActivityContext as IDataAccessContext,
         typeof(DefaultActionPlan).FullName,
         objectId
       )));

      return RemoveAclData(defaultActionPlan);
   }
}

IDataAccess:

public interface IDataAccessTemplate : IServiceTemplate
{ //empty for now    }

IServiceTemplate:

public interface IServiceTemplate
{
   Task<TReply> InvokeAsync<TReply>(Func<ITemplateContext, Task<TReply>> invokeCallback);

   Task<TReply> InvokeAsync<TReply>(Func<ITemplateContext, Task<TReply>> invokeCallback, Action<ITemplateContext, Exception> errorCallback);
}

错误:

  

发现System.NotSupportedException HResult = -2146233067     消息=不支持的表达式:context =&gt; FromResult(new DefaultActionPlan())     源= Moq的

     

堆栈跟踪:          在Moq.MatcherFactory.CreateMatcher(表达式表达式,布尔isParams)          在Moq.MethodCall..ctor(模拟模拟,条件条件,表达式originalExpression,MethodInfo方法,Expression []参数)          在Moq.MethodCallReturn..ctor(模拟模拟,条件条件,表达式originalExpression,MethodInfo方法,Expression []参数)          在Moq.MethodCallReturn 2..ctor(Mock mock, Condition condition, Expression originalExpression, MethodInfo method, Expression[] arguments) at Moq.Mock.<>c__DisplayClass1c 2.b__1b()          在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表达式)          at DataService.Tests.Controllers.ActionPlan.PlanProviderTest.d__3.MoveNext()in c:\ Source ... \ Dev \ DataService.Tests \ Controllers \ Plan \ PlanProviderTest.cs:第52行     InnerException:

1 个答案:

答案 0 :(得分:0)

不确定这是否会改变任何事情,而不是这样做:

context => Task.FromResult(new DefaultActionPlan())

试试这个:

context => Task.FromResult(It.IsAny<DefaultActionPlan>())

并可能将您的回报更改为:

.ReturnsAsync(new DefaultActionPlan());