Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/azure/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 单元测试-模拟-可重写的问题-扩展方法_C#_Azure_Unit Testing_Mocking_Moq - Fatal编程技术网

C# 单元测试-模拟-可重写的问题-扩展方法

C# 单元测试-模拟-可重写的问题-扩展方法,c#,azure,unit-testing,mocking,moq,C#,Azure,Unit Testing,Mocking,Moq,我正在尝试为以下Azure搜索方法编写单元测试: public async Task Write(ISearchIndexClient indexClient, Search search) { await UploadContents(indexClient, search.SearchContents); } private static async Task UploadContents(ISearchIndexClient indexClient, IReadOnlyColle

我正在尝试为以下Azure搜索方法编写单元测试:

public async Task Write(ISearchIndexClient indexClient, Search search)
{
    await UploadContents(indexClient, search.SearchContents);
}

private static async Task UploadContents(ISearchIndexClient indexClient, IReadOnlyCollection<dynamic> searchContents) => await Task.Run(() => indexClient.Documents.Index(IndexBatch.Upload(searchContents)));
公共异步任务写入(ISearchIndexClient indexClient,搜索)
{
等待上传内容(indexClient、search.SearchContents);
}
私有静态异步任务上载内容(ISearchIndexClient indexClient,IReadOnlyCollection searchContents)=>等待任务运行(()=>indexClient.Documents.Index(IndexBatch.Upload(searchContents));
单元测试代码1:

public async Task Write_Success()
{
    var searchIndexClientMock = new Mock<ISearchIndexClient>();
    searchIndexClientMock
        .Setup(x => x.Documents.Index(It.IsAny<IndexBatch<Document>>(), It.IsAny<SearchRequestOptions>()))
        .Returns(It.IsAny<DocumentIndexResult>()).Callback(() => IndexBatch.Upload(It.IsAny<IEnumerable<Document>>()));

    var pushFunction = new SearchIndexWriter();

    Search search = new Search();

    await pushFunction.Write(searchIndexClientMock.Object, search);

    //Assert, Verify checks
}
公共异步任务写入成功()
{
var searchIndexClientMock=new Mock();
searchIndexClientMock
.Setup(x=>x.Documents.Index(It.IsAny(),It.IsAny())
.Returns(It.IsAny()).Callback(()=>IndexBatch.Upload(It.IsAny());
var pushFunction=新的SearchIndexWriter();
搜索=新搜索();
等待pushFunction.Write(searchIndexClientMock.Object,search);
//断言、验证检查
}
我得到以下错误:

消息:System.NotSupportedException:不支持的表达式:…=>。。。。索引(It.IsAny>(),It.IsAny()) 在设置/验证表达式中不能使用扩展方法(此处:DocumentsOperationsExtensions.Index)

单元测试代码2:

public async Task Write_Success()
{
    var searchIndexClientMock = new Mock<ISearchIndexClient>();
    searchIndexClientMock
        .SetupGet(x => x.Documents).Returns(It.IsAny<IDocumentsOperations>());

    var pushFunction = new SearchIndexWriter();

    var search = new Search()
    {
        SearchContents = new List<dynamic>(),
    };

    await pushFunction.Write(searchIndexClientMock.Object, search);

    //Verify, Assert logic
}
公共异步任务写入成功()
{
var searchIndexClientMock=new Mock();
searchIndexClientMock
.SetupGet(x=>x.Documents).Returns(It.IsAny());
var pushFunction=新的SearchIndexWriter();
var search=新搜索()
{
SearchContents=新列表(),
};
等待pushFunction.Write(searchIndexClientMock.Object,search);
//验证、断言逻辑
}
我得到以下错误:

消息:System.NullReferenceException:对象引用未设置为对象的实例。
在Microsoft.Azure.Search.DocumentsOperationsExtensions.IndexAsync[T](IDocumentsOperations,IndexBatch ^1批,SearchRequestOptions SearchRequestOptions,CancellationToken CancellationToken)
在Microsoft.Azure.Search.DocumentsOperationsExtensions.Index[T](IDocumentsOperations,IndexBatch ^1批,SearchRequestOptions SearchRequestOptions)

如何测试上传功能?

根据文档

只有一个方法
索引
,它有两个参数

UploadContent
方法中,Index方法只传递一个参数。这两个项目是否存在版本差异

而且

searchIndexClientMock
        .SetupGet(x => x.Documents).Returns(It.IsAny<IDocumentsOperations>());
SearchIndexClientLock
.SetupGet(x=>x.Documents).Returns(It.IsAny());

在设置中,返回应该是一个具体实例,而不是执行它。IsAny()

您基本上是在尝试测试第三方依赖项的功能。尽管这些依赖项有可以模仿的抽象,但它们需要不必要的设置来隔离它们进行单元测试,这对我来说是一种代码味道

我建议抽象出第三方依赖关系

private readonly ISearchService service;

//...assuming service injected
public SearchIndexWriter(ISearchService service) {
    this.service = service;
}

public Task Write(ISearchIndexClient indexClient, Search search) {
    return service.UploadContents(indexClient, search.SearchContents);
}
public class SearchService : ISearchService  {
    private Task UploadContents(ISearchIndexClient indexClient, IReadOnlyCollection<dynamic> searchContents) 
        =>  indexClient.Documents.IndexAsync(IndexBatch.Upload(searchContents));
}
尽量避免与静态问题紧密耦合,因为这会使隔离的单元测试变得困难

服务定义可以如下所示

public interface ISearchService {
    Task UploadContents(ISearchIndexClient indexClient, IReadOnlyCollection<dynamic> searchContents);
}
公共接口ISearchService{
任务上载内容(ISearchIndexClient indexClient、IReadOnlyCollection searchContents);
}
用一个简单的实现包装外部依赖关系

private readonly ISearchService service;

//...assuming service injected
public SearchIndexWriter(ISearchService service) {
    this.service = service;
}

public Task Write(ISearchIndexClient indexClient, Search search) {
    return service.UploadContents(indexClient, search.SearchContents);
}
public class SearchService : ISearchService  {
    private Task UploadContents(ISearchIndexClient indexClient, IReadOnlyCollection<dynamic> searchContents) 
        =>  indexClient.Documents.IndexAsync(IndexBatch.Upload(searchContents));
}
公共类搜索服务:ISearchService{
私有任务上载内容(ISearchIndexClient indexClient、IReadOnlyCollection searchContents)
=>indexClient.Documents.IndexAsync(IndexBatch.Upload(searchContents));
}
不要过分强调测试你无法控制的代码。相反,把注意力集中在你可以控制的逻辑上

public async Task Write_Success() {
    //Arrange
    var serviceMock = new Mock<ISearchService>();
    serviceMock
        .Setup(_ => _.UploadContents(It.IsAny<ISearchIndexClient>(), It.IsAny<IReadOnlyCollection<It.AnyType>>())
        .ReturnsAsync(new object());

    var searchIndexClientMock = Mock.Of<ISearchIndexClient>();

    var pushFunction = new SearchIndexWriter(serviceMock.Object);

    Search search = new Search();

    //Act
    await pushFunction.Write(searchIndexClientMock.Object, search);

    //Assert, Verify checks
    //...
}
公共异步任务写入成功(){
//安排
var serviceMock=new Mock();
serviceMock
.Setup(=>u.UploadContents(It.IsAny(),It.IsAny())
.ReturnsAsync(新对象());
var searchIndexClientMock=Mock.Of();
var pushFunction=新的SearchIndexWriter(serviceMock.Object);
搜索=新搜索();
//表演
等待pushFunction.Write(searchIndexClientMock.Object,search);
//断言、验证检查
//...
}