Jmoney38
Jmoney38

Reputation: 3314

How to mock StoredProcedureResponse

The question is pretty simple. I've Moq'ed an IDocumentClient (which is the main DocumentDB .NET client). I am Moq'ing the ExecuteStoredProcedureAsync() method. It returns a StoredProcedureResponse type (a concrete type), but its interface is very locked down.

I figured I could just create a StoredProcedureResponse and embed my payload into the Response property, but it's setter is private. Moreover, the only constructor is parameterless.

What am I missing here? It would be ideal if the method returned an interface type (IStoredProcedureResponse), but I don't have control over that. I realize I could write a wrapper around the IDocumentClient, but that's not feasible.

The only thing I can think of is to extend and forcefully override the property with the "new" keyword - BUT, in the actual calling code, I would have a terrible hack in which I check the runtime type and downcast in order to use the override Resource property.

Upvotes: 4

Views: 912

Answers (3)

Bagroy
Bagroy

Reputation: 75

By reading the comments I found a simple solution:

var response = new StoredProcedureResponse<T>();
response.GetType().InvokeMember("responseBody",
                BindingFlags.Instance | BindingFlags.SetField | BindingFlags.NonPublic, Type.DefaultBinder, response, new object[] {new T()});

Upvotes: 1

CodingYoshi
CodingYoshi

Reputation: 27039

Use reflection to create it:

Type type=typeof(StoredProcedureResponse);
var spr = (StoredProcedureResponse)Activator.CreateInstance(type,true);

and set the properties and whatever else you need using reflection as well:

spr.GetType().InvokeMember("PropertyName",
BindingFlags.Instance | BindingFlags.Public | BindingFlags.SetProperty,
Type.DefaultBinder, obj, "MyName");

Upvotes: 0

Eric
Eric

Reputation: 1847

Is the IDocumentClient interface required at your top level? If not, you could create a service interface:

public interface IDocumentService
{
    Task<IStoredProcedureResponse<T>> ExecuteStoredProcedureAsync<T>(string query, IEnumerable<object> parameters);
}

In this case, or one similar, you could then implement a live service that uses DocumentClient and a mock service that just returns a mocked IStoredProcedureResponse.

Incidentally, I find it odd that IDocumentClient.ExecuteStoredProcedureAsync returns a concrete instance that ALSO happens to inherit from an interface.

Upvotes: 1

Related Questions