2017-02-09 64 views
1

我正在用我的一個測試掙扎了一下。MStest任務結果爲空

下面是我測試

public async Task Handle(ReceiveEventsFromSalesForceCommand message, IMessageHandlerContext context) 
{ 
    var queryResult = await this.GenerateQueryResultAsync(message).ConfigureAwait(false); 

    await this.DetermineActionAsync(context, queryResult).ConfigureAwait(false); 
} 

public async Task<QueryResult<EventStore__c>> GenerateQueryResultAsync(ReceiveEventsFromSalesForceCommand message) 
{ 
    QueryResult<EventStore__c> queryResult; 
    if (string.IsNullOrWhiteSpace(message.NextRecordsUrl)) 
     { 
      queryResult = await this.forceClient.QueryAsync<EventStore__c>(query).ConfigureAwait(false); 
      this.log.Info($"AFTER: QueryAllAsync<EventStore>(query), found {queryResult?.TotalSize ?? 0} records"); 
     } 
     else 
     { 
      queryResult = await this.forceClient.QueryContinuationAsync<EventStore__c>(message.NextRecordsUrl).ConfigureAwait(false); 
      this.log.Info("AFTER: QueryContinuationAsync<EventStore>(query)"); 
     } 
    return queryResult; 
} 

的代碼,這是我的單元測試

[TestMethod] 
    public async Task Test() 
    { 
     // arrange 
     var forceConfig = Substitute.For<ISalesForceCreationHandlerConfig>(); 
     var forceClient = Substitute.For<IForceClient>(); 
     forceClient.QueryAllAsync<EventStore__c>(Arg.Any<string>()).Returns(Task.FromResult(new QueryResult<EventStore__c> { NextRecordsUrl = "Dummy" })); 
     var messageHandlerContext = Substitute.For<IMessageHandlerContext>(); 
     var handler = new SalesForceBatchCreationHandler(forceClient, null, forceConfig); 

     // act 
     await handler.Handle(new ReceiveEventsFromSalesForceCommand(), messageHandlerContext); 

     // assert 
     await messageHandlerContext.Received().Send(Arg.Is<ReceiveEventsFromSalesForceCommand>(command => string.IsNullOrWhiteSpace(command.NextRecordsUrl)), Arg.Any<SendOptions>()); 
     await messageHandlerContext.DidNotReceive().SendLocal(Arg.Any<PublishMultipleKlantManagementEnvelopeCreatedEventsCommand>()); 
    } 

我的問題是我的GenerateQueryResultAsync方法是iresult被null,我得到一個NullReferenceException。我如何確保結果不爲空並避免異常?

+1

備註:在第一個方法'Handle'中,省略異步/等待會更有效率。只需直接返回任務,因爲沒有理由在該方法中等待其完成(除非您在方法中未顯示任何內容)。 – Igor

+1

是否有一個原因,爲什麼這不應該作爲http://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-and-how-doi-i-fix-it重複關閉?是什麼讓你的案例變得特別,你不能簡單地在你需要它的地方有一個非空值? – nvoigt

+1

您使用NSubstitute 1.9.0或更高版本嗎?看起來你正在扼殺'QueryAllAsync',但SUT正在調用'QueryAsync'。 –

回答

0

重構您進行異步調用的方式。最有可能的是這個{queryResult.TotalSize}是罪魁禍首。

public async Task<QueryResult<EventStore__c>> GenerateQueryResultAsync(ReceiveEventsFromSalesForceCommand message) { 
    QueryResult<EventStore__c> queryResult; 
    if (string.IsNullOrWhiteSpace(message.NextRecordsUrl)) { 
     queryResult = await this.forceClient.QueryAsync<EventStore__c>(query).ConfigureAwait(false); 
     this.log.Info($"AFTER: QueryAllAsync<EventStore>(query), found {queryResult?.TotalSize ?? 0} records"); 
    } else { 
     queryResult = await this.forceClient.QueryContinuationAsync<EventStore__c>(message.NextRecordsUrl).ConfigureAwait(false); 
     this.log.Info("AFTER: QueryContinuationAsync<EventStore>(query)"); 
    } 
    return queryResult; 
} 
+0

我編輯了句柄方法,我需要queryresult作爲另一種方法的輸入。 queryResult.TotalSize確實是罪魁禍首。但它返回的queryresult現在爲空。我覺得我在單元測試中缺少某種配置? –

+0

@RonaldRozema然後你需要檢查/調試'forceClient.QueryAsync'方法來查看它爲什麼返回null。該方法中的某些內容會導致返回空結果。 – Nkosi