c# - Azure Cosmos/Document DB ResourceResponse<Document> 使用反射错误进行单元测试

标签 c# azure azure-cosmosdb

我正在使用下面 URL 中提供的代码片段来实例化 ResourceResponse 以进行单元测试模拟目的

https://github.com/Azure/azure-cosmosdb-dotnet/issues/342#issuecomment-367827999

但是我在给定行遇到以下错误:

var documentServiceResponse = Activator.CreateInstance(documentServiceResponseType, flags, null, arguments, null);

System.MissingMethodException: 'Constructor on type 'Microsoft.Azure.Documents.DocumentServiceResponse' not found.'

最终我想模拟像 RequestCharge 这样的 Response 属性。

请建议如何实现这一目标。

提前致谢

最佳答案

您可以通过添加 Cosmonaut's TestingExtensions 来做到这一点

这是一个扩展方法,可将任何对象转换为 ResourceReponse

public static ResourceResponse<T> ToResourceResponse<T>(this T resource, HttpStatusCode statusCode, IDictionary<string, string> responseHeaders = null) where T : Resource, new()
{
    var resourceResponse = new ResourceResponse<T>(resource);
    var documentServiceResponseType = Type.GetType("Microsoft.Azure.Documents.DocumentServiceResponse, Microsoft.Azure.DocumentDB.Core, Version=1.9.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35");

    var flags = BindingFlags.NonPublic | BindingFlags.Instance;

    var headers = new NameValueCollection { { "x-ms-request-charge", "0" } };

    if (responseHeaders != null)
    {
        foreach (var responseHeader in responseHeaders)
        {
            headers[responseHeader.Key] = responseHeader.Value;
        }
    }

    var arguments = new object[] { Stream.Null, headers, statusCode, null };

    var documentServiceResponse =
        documentServiceResponseType.GetTypeInfo().GetConstructors(flags)[0].Invoke(arguments);

    var responseField = typeof(ResourceResponse<T>).GetTypeInfo().GetField("response", BindingFlags.NonPublic | BindingFlags.Instance);

    responseField?.SetValue(resourceResponse, documentServiceResponse);

    return resourceResponse;
}

这仅适用于 2.0.0 之前的 SDK 版本。

对于 2.0.0 后的版本,请使用此版本。

public static ResourceResponse<T> ToResourceResponse<T>(this T resource, HttpStatusCode statusCode, IDictionary<string, string> responseHeaders = null) where T : Resource, new()
{
    var resourceResponse = new ResourceResponse<T>(resource);
    var documentServiceResponseType = Type.GetType("Microsoft.Azure.Documents.DocumentServiceResponse, Microsoft.Azure.DocumentDB.Core, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35");

    var flags = BindingFlags.NonPublic | BindingFlags.Instance;

    var headers = new NameValueCollection { { "x-ms-request-charge", "0" } };

    if (responseHeaders != null)
    {
        foreach (var responseHeader in responseHeaders)
        {
            headers[responseHeader.Key] = responseHeader.Value;
        }
    }

    var headersDictionaryType = Type.GetType("Microsoft.Azure.Documents.Collections.DictionaryNameValueCollection, Microsoft.Azure.DocumentDB.Core, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35");

    var headersDictionaryInstance = Activator.CreateInstance(headersDictionaryType, headers);

    var arguments = new [] { Stream.Null, headersDictionaryInstance, statusCode, null };

    var documentServiceResponse = documentServiceResponseType.GetTypeInfo().GetConstructors(flags)[0].Invoke(arguments);

    var responseField = typeof(ResourceResponse<T>).GetTypeInfo().GetField("response", flags);

    responseField?.SetValue(resourceResponse, documentServiceResponse);

    return resourceResponse;
}

您可以阅读有关 CosmosDB C# 代码单元测试的更多信息 here

关于c# - Azure Cosmos/Document DB ResourceResponse<Document> 使用反射错误进行单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52276063/

相关文章:

azure - 无法使用 StorageClient 1.7.1 运行 Azure 项目

c# - azure documentdb 创建文档重复项 Id 属性

c# - 是否可以在 C# 中更改 HTTP header 的顺序(使用任何外部库)?

c# - 如何让我的弹出窗口在 ASP.NET MVC 中的 AJAX 调用的提交按钮上关闭?

azure - 从 Databricks 笔记本中删除 Azure SQL 表

node.js - Azure MongoDB find操作查询时间很慢

azure - 如何使用 Powershell 从订阅获取 Cosmos DB 的数据大小

c# - 身份在 Asp .Net MVC 5 中如何工作

c# - TCP 文件传输 - 几个字节错误

azure - 如何从 Azure DevOps 管道运行 "docker login azure"