Reputation: 6752
I am trying to mock a call that returns ResourceResponse<Document>
, but I am not able to instantiate that type. Is there a factory class that can instantiate it or some other way to do so?
EDIT
var response = new ResourceResponse<Document>();
The type 'Microsoft.Azure.Documents.Client.ResourceResponse' has no constructors defined
Upvotes: 9
Views: 3418
Reputation: 11
The ResourceResponse class
has the constructor that contains the DocumentServiceResponse parameter marked as internal.
This is bad because even though you can create a ResourceReponse
object from your DTO class
you cannot set things like RUs consumed, response code and pretty much anything else because they are all coming from the ResourceResponseBase which also has the DocumentServiceResponse marked as internal.
Please find code at below link
Upvotes: 1
Reputation: 8346
Kinda late but with Microsoft.Azure.DocumentDB.Core 2.4.2 there's a DocumentClient
constructor that accepts an HttpMessageHandler
as a parameter. It's ugly (so much so it deserves a downvote) but you can use this to inject responses with status codes. As far as I can tell nothing's leaving my box when I do this.
I also had to create a test-only constructor since I would never want to use this during running code. But for anyone still interested until a better library comes out here are the relevant parts.
Create your client
var client = new DocumentClient(host, authText, handler);
In your tests you can use a mocked handler like this:
public static Mock<HttpMessageHandler> CreateHttpMessageHandler(List<HttpResponseMessage> responses)
{
var handlerMock = new Mock<HttpMessageHandler>(MockBehavior.Strict);
handlerMock.Protected()
.Setup<Task<HttpResponseMessage>>(
nameof(HttpClient.SendAsync),
ItExpr.IsAny<HttpRequestMessage>(),
ItExpr.IsAny<CancellationToken>())
.ReturnsAsync(() => {
var response = responses[0];
responses.RemoveAt(0);
return response;
})
.Verifiable();
return handlerMock;
}
I created this response factory simulator
private HttpResponseMessage Respond(string text)
{
var response = new HttpResponseMessage(HttpStatusCode.OK)
{
StatusCode = HttpStatusCode.OK,
Content = new StringContent(text),
};
return response;
}
and set up the handler with something like this:
var responses = new List<HttpResponseMessage> {
Respond("{ ... }"),
Respond("{ ... }"),
Respond("{ ... }"),
Respond("{ ... }"),
};
Replace the ...
with your Fiddler (or similar) trace output from an actual call to your CosmosDB. FWIW I had to supply 2 copies of my actual payload as the final 2 responses. This is obviously AS-IS and SUBJECT TO CHANGE but It worked for me
. Hope it helps you and looking forward to a modern library designed to interfaces with SOLID principles.
Upvotes: 0
Reputation: 317
The latest stable version of Microsoft.Azure.DocumentDB (1.10.0) atm added 2 constructors for mocking purposes.
https://msdn.microsoft.com/en-us/library/azure/dn799209.aspx#Anchor_2
Edit
Using Moq you could do something like this:
Mock<IDocumentClient> documentClient = new Mock<IDocumentClient>();
documentClient
.Setup(dc => dc.ReplaceDocumentAsync(UriFactory.CreateDocumentUri("database", "collection", "id"), object, null) // last parameter are RequestOptions, these are null by default
.Returns(Task.FromResult(new ResourceResponse<Document>()));
This way I can check if the method on my documentClient is being called, if you want to influence what is returned in the document, you have to create a document, and following that a ResourceResponse of that document. Something like:
var document = new Document();
document.LoadFrom(jsonReader); // the json reader should contain the json of the document you want to return
Mock<IDocumentClient> documentClient = new Mock<IDocumentClient>();
documentClient
.Setup(dc => dc.ReplaceDocumentAsync(UriFactory.CreateDocumentUri("database", "collection", "id"), object, null) // last parameter are RequestOptions, these are null by default
.Returns(Task.FromResult(new ResourceResponse<Document>(document)));
Upvotes: 7