Reputation: 265
I am using the code snippet provided in below URL for instantiating ResourceResponse for unit test mocking purpose
https://github.com/Azure/azure-cosmosdb-dotnet/issues/342#issuecomment-367827999
But I am getting below error at given line:
var documentServiceResponse = Activator.CreateInstance(documentServiceResponseType, flags, null, arguments, null);
System.MissingMethodException: 'Constructor on type 'Microsoft.Azure.Documents.DocumentServiceResponse' not found.'
Ultimately I want to mock Response properties like RequestCharge.
Please suggest how t achieve that.
Thanks in advance
Upvotes: 2
Views: 992
Reputation: 7200
You can do that by adding Cosmonaut's TestingExtensions
Here is an extension method that convert any object to a 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;
}
This will only work for pre-2.0.0 SDK versions.
For post 2.0.0 use this one instead.
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;
}
You can read more about CosmosDB C# code unit testing here
Upvotes: 1