簡體   English   中英

盡管定義了返回對象,但NSubstitute Async返回null

[英]NSubstitute Async returns null despite defined return object

我有一個單元測試,應該返回指定的對象,但返回的是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返回空的eferytime並調試測試t為空,因為GetDefaultActionPlan沒有返回jj而是空了?

我想念jj回來了嗎?


編輯:

Eris和Gabe都正確地指出,我的IEntityStore的Mock值還不足夠...即使它指定了返回值也不會傳遞給包裝的InvokeAsync,因此我也需要模擬InvokeAsync。

由於傳遞了Arg,Gabe的回答略有偏離。任何人都不滿足InvokeAsync所需的參數。 但是,我對此並沒有責怪他,因為我花了一個小時來跟蹤多個項目(這是一家大公司)之間的繼承鏈。 他無權執行的操作。

最后是成功的代碼:

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

雖然在您的代碼中沒有看到此信息,但我將假定GetDefaultActionPlan返回defaultActionPlan變量,並且Template.InvokeAsync引用通過構造函數傳遞的IDataAccessTemplate。

您似乎缺少了Template.InvokeAsync的模擬返回值,並且由於它包裝了另一個調用,因此您唯一關心的是它的返回值:

var estore = Substitute.For<IEntityStore>();
var dataAccessTemplate = Substitute.For<IDataAccessTemplate>();
dataAccessTemplate.InvokeAsync(context => Task.FromResult(Arg.Any<DefaultActionPlan>)
    .ReturnsForAnyArgs(jj);

var pdp = new PlanDataProvider(dataAccessTemplate, estore);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM