You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Xunit和Moq无法为IndexDocumentsAsync设置预期

问题描述

我有一个向Azure认知搜索插入文档的方法,却难以对其进行单元测试。我的方法如下:

public async Task AddDocumentIntoIndexAsync(Document[] Documents, string IndexName)
{
    IndexDocumentsBatch<CreClaim> batch = IndexDocumentsBatch.MergeOrUpload(Documents);
    try
    {
        IndexDocumentsResult result = await _searchClient.IndexDocumentsAsync(batch);
       
    }
    catch (Exception ex)
    {
       
    }
}

我通过依赖注入注入类型为Azure.Search.Documents.SearchClient的_searchClient实例。在单元测试项目中,我按如下方式模拟SearchClient:

_searchClient = new Mock<SearchClient>(new Uri(endpoint),indexName, new AzureKeyCredential(key));

问题出在尝试设置IndexDocumentsAsync时:

var indexresult = SearchModelFactory.IndexDocumentsResult;
_searchClient.Setup(x => x.IndexDocumentsAsync(batch, options, new CancellationToken())).Returns(indexresult);

运行时出现错误:

Invalid callback. Setup on method with 3 parameter(s) cannot invoke callback with different number of parameters (1).

我以为最后两个参数是可选的,于是尝试:

_searchClient.Setup(x => x.IndexDocumentsAsync(batch)).Returns(indexresult);

但出现编译问题,有人能帮忙解决吗?

解决方案

问题根源

  1. SearchClient.IndexDocumentsAsync的重载方法需要严格匹配签名,你调用的版本接收IndexDocumentsBatch<T>和可选的IndexDocumentsOptions、CancellationToken,但Moq无法自动处理可选参数的省略,且异步方法必须返回Task<IndexDocumentsResult>而非直接返回结果。
  2. SearchModelFactory.IndexDocumentsResult是工厂方法,需要调用(带括号)才能生成实例,不能直接引用方法本身。

正确的测试设置步骤

  1. 生成有效返回结果
    调用工厂方法创建IndexDocumentsResult实例:

    var indexResult = SearchModelFactory.IndexDocumentsResult();
    
  2. 匹配正确重载并设置异步返回
    使用It.IsAny<T>灵活匹配参数,同时用ReturnsAsync返回异步任务:

    // 匹配你实际调用的重载:仅传入batch,其余参数用默认值
    _searchClient
        .Setup(x => x.IndexDocumentsAsync(It.IsAny<IndexDocumentsBatch<CreClaim>>(), null, default(CancellationToken)))
        .ReturnsAsync(indexResult);
    

    若需要宽松匹配所有参数组合:

    _searchClient
        .Setup(x => x.IndexDocumentsAsync(It.IsAny<IndexDocumentsBatch<CreClaim>>(), It.IsAny<IndexDocumentsOptions>(), It.IsAny<CancellationToken>()))
        .ReturnsAsync(indexResult);
    
  3. 验证方法调用(可选)
    测试完成后可验证方法是否被正确调用:

    _searchClient.Verify(x => x.IndexDocumentsAsync(It.IsAny<IndexDocumentsBatch<CreClaim>>(), null, default), Times.Once);
    

注意事项

  • 确保测试项目引用的Azure.Search.Documents和Moq包版本与主项目兼容。
  • 若CreClaim类型有特定约束,要保证测试中传入的Document[]能正确转换为IndexDocumentsBatch<CreClaim>。

内容的提问来源于stack exchange,提问作者Tarun Bhatt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 17:31:57