尽管定义了返回对象

时间:2016-06-15 14:06:53

标签: c# unit-testing asynchronous

我有一个单元测试应该返回指定的对象,但它返回null。

要测试的数据提供者:

public class PlanDataProvider : BaseDomainServiceProvider, IPlanDataProvider
{
    //CTOR
    public PlanDataProvider(IDataAccessTemplate template, IEntityStore entityStore) : base(template, entityStore)
    {
    }

    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
            )));
    }
}

测试:

public async Task GetPlan_BadPlanID()
{
   //Arrange
   string badPlanId = "57509afbc6b48d3f33b2dfcd";

   ...snip...

   DefaultActionPlan jj = new ObjectId(badPlanId);

   //create EntityStore object
   var dataxs = Substitute.For<IDataAccessContext>();
   var estore = Substitute.For<IEntityStore>();
   estore.GetEntityById<DefaultActionPlan, ObjectId>(
        dataxs, 
        typeof(DefaultActionPlan).FullName, 
        new ObjectId(badPlanId))
   .Returns(Task.FromResult(jj).Result);

   var dataAccessTemplate = Substitute.For<IDataAccessTemplate>();

   PlanDataProvider pdp = new PlanDataProvider(dataAccessTemplate, estore);

   //Act
   var t = await pdp.GetDefaultActionPlan(badPlanId);
   //Now this confuses me as the compiler thinks t is DefaultActionPlan NOT Task<DefaultActionPlan>???
}

无论如何t返回null eferytime并调试测试t为null因为GetDefaultActionPlan没有返回jj而是null?

我错过了让jj返回的内容?

编辑:

Eris和Gabe都正确地指出我的IEntityStore模拟不足以满足该值...即使它指定返回也不会传递给包装InvokeAsync,因此我也需要模拟InvokeAsync。 / p>

Gabe的回答略微偏离,因为传递Arg.Any不满足InvokeAsync所需的parms。但是我并不是因为我花了一个小时跟踪多个项目的继承链(这是一家大公司)。他无法做的事情。

最后,这里是导致成功的代码:

var estore = Substitute.For<IEntityStore>();
var dataAccessTemplate = Substitute.For<IDataAccessTemplate>();
dataAccessTemplate.InvokeAsync(context => Task.FromResult(
      estore.GetEntityById<DefaultActionPlan>(
               dataxs, typeof(DefaultActionPlan).FullName, new ObjectId(badPlanId))))
.ReturnsForAnyArgs(jj);

var pdp = new PlanDataProvider(dataAccessTemplate, estore);

1 个答案:

答案 0 :(得分:3)

虽然我在代码中没有看到这一点,但我会假设GetDefaultActionPlan返回defaultActionPlan变量,而Template.InvokeAsync指的是通过构造函数传入的IDataAccessTemplate。

看起来你缺少Template.InvokeAsync的模拟返回值,并且因为它正在包装另一个调用,所以它的返回值是你唯一关心的值:

index