Azure Cosmos / Document DB ResourceResponse 使用反射误差进行单元测试

问题描述 投票:1回答:1

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

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

但是我在给定的行下面的误差低于:

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

System.MissingMethodException:'找不到'Microsoft.Azure.Documents.DocumentServiceResponse'类型的构造函数。

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

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

提前致谢

c# azure azure-cosmosdb
1个回答
1
投票

你可以通过添加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的更多信息

© www.soinside.com 2019 - 2024. All rights reserved.