C# MStest任务结果为空

C# MStest任务结果为空,c#,unit-testing,asynchronous,mstest,C#,Unit Testing,Asynchronous,Mstest,我的一个测试有点困难 这是我正在测试的代码 public async Task Handle(ReceiveEventsFromSalesForceCommand message, IMessageHandlerContext context) { var queryResult = await this.GenerateQueryResultAsync(message).ConfigureAwait(false); await this.DetermineActionAsyn

我的一个测试有点困难

这是我正在测试的代码

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;
}
公共异步任务句柄(ReceiveEventsFromSalesForceCommand消息,IMessageHandlerContext)
{
var queryResult=wait this.GenerateQueryResultAsync(message).configureWait(false);
等待此消息。DetermineActionAsync(上下文,queryResult)。ConfigureAwait(false);
}
公共异步任务生成器ResultAsync(从SalesForceCommand消息接收事件)
{
QueryResult QueryResult;
if(string.IsNullOrWhiteSpace(message.NextRecordsUrl))
{
queryResult=wait this.forceClient.QueryAsync(query).configureWait(false);
this.log.Info($”在:queryalAsync(查询)之后,找到了{queryResult?.TotalSize±0}条记录”);
}
其他的
{
queryResult=Wait this.forceClient.QueryContinuationAsync(message.NextRecordsUrl).ConfigureWait(false);
this.log.Info(“之后:QueryContinuationAsync(query)”;
}
返回查询结果;
}
这是我的单元测试

[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>());
    }
[TestMethod]
公共异步任务测试()
{
//安排
var forceConfig=Substitute.For();
var forceClient=Substitute.For();
queryalAsync(Arg.Any()).Returns(Task.FromResult(newqueryResult{NextRecordsUrl=“Dummy”}));
var messageHandlerContext=Substitute.For();
var handler=新的SalesForceBatchCreationHandler(forceClient,null,forceConfig);
//表演
wait handler.Handle(新的ReceiveEventsFromSalesForceCommand(),messageHandlerContext);
//断言
等待messageHandlerContext.Received().Send(Arg.Is(command=>string.IsNullOrWhiteSpace(command.NextRecordsUrl)),Arg.Any());
等待messageHandlerContext.DidNotReceive().SendLocal(Arg.Any());
}

我的问题是我的
GenerateQueryResultAsync
方法的结果是
null
,我得到了一个NullReferenceException。如何确保结果不为null并避免异常

重新构造异步调用的方式。最有可能的原因是
{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;
}
公共异步任务生成器ResultAsync(ReceiveEventsFromSalesForceCommand消息){
QueryResult QueryResult;
if(string.IsNullOrWhiteSpace(message.NextRecordsUrl)){
queryResult=wait this.forceClient.QueryAsync(query).configureWait(false);
this.log.Info($”在:queryalAsync(查询)之后,找到了{queryResult?.TotalSize±0}条记录”);
}否则{
queryResult=Wait this.forceClient.QueryContinuationAsync(message.NextRecordsUrl).ConfigureWait(false);
this.log.Info(“之后:QueryContinuationAsync(query)”;
}
返回查询结果;
}

重新构造异步调用的方式。最有可能的原因是
{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;
}
公共异步任务生成器ResultAsync(ReceiveEventsFromSalesForceCommand消息){
QueryResult QueryResult;
if(string.IsNullOrWhiteSpace(message.NextRecordsUrl)){
queryResult=wait this.forceClient.QueryAsync(query).configureWait(false);
this.log.Info($”在:queryalAsync(查询)之后,找到了{queryResult?.TotalSize±0}条记录”);
}否则{
queryResult=Wait this.forceClient.QueryContinuationAsync(message.NextRecordsUrl).ConfigureWait(false);
this.log.Info(“之后:QueryContinuationAsync(query)”;
}
返回查询结果;
}

旁注:在第一个方法
Handle
中,省略async/await会更有效。直接返回任务,因为没有理由在该方法中等待任务完成(除非您在该方法中没有向我们显示某些内容)。是否有理由不将其作为副本关闭?是什么让您的案例如此特殊,以至于您不能在需要的地方简单地使用非空值?您使用的是NSubstitute 1.9.0或更高版本吗?看起来你在stubing
queryalasync
但是SUT正在呼叫
QueryAsync
@StephenCleary谢谢,我完全错过了那个细节。注意:在您的第一个方法
Handle
中,省略async/await会更有效。直接返回任务,因为没有理由在该方法中等待任务完成(除非您在该方法中没有向我们显示某些内容)。是否有理由不将其作为副本关闭?是什么让您的案例如此特殊,以至于您不能在需要的地方简单地使用非空值?您使用的是NSubstitute 1.9.0或更高版本吗?看起来你在stubing
queryalasync
但是SUT正在呼叫
QueryAsync
@StephenCleary谢谢,我完全错过了那个细节。修复了它hahaI已经编辑了handle方法,我需要queryresult作为另一个方法的输入。queryResult.TotalSize确实是罪魁祸首。但是它返回的queryresult现在为空。我觉得我在单元测试中缺少了某种配置?@RonaldRozema然后你需要检查/调试
forceClient.QueryAsync
方法,看看它为什么返回null。该方法中的某些内容导致返回空结果。我已经编辑了handle方法,我需要queryresult作为另一个方法的输入。queryResult.TotalSize确实是罪魁祸首。但是它返回的queryresult现在为空。我觉得我在单元测试中缺少了某种配置?@RonaldRozema然后你需要检查/调试
forceClient.QueryAsync
方法,看看它为什么返回null。该方法中的某些内容导致返回空结果。