Jonas Stawski
Jonas Stawski

Reputation: 6752

How to instantiate ResourceResponse<Document>

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

Answers (3)

Magical Creations
Magical Creations

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

how-to-mock-or-instantiate

Upvotes: 1

No Refunds No Returns
No Refunds No Returns

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

YentheO
YentheO

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

Related Questions