Reputation: 157
I'm having issues mocking a delegate that returns an IHttpClient
. This is by requirement of the client, and I cannot change the implementation.
The code looks something like this:
Delegate:
namespace Foo.Http
{
public delegate IHttpClient FooHttpClientProvider(string name);
}
Test class:
[SetUp]
public void SetUp()
{
Mock<FooHttpClientProvider>().Setup(x => x("HttpClient")).Returns(Mock<IHttpClient>().Object);
}
When I do this, I get the following exception:
System.InvalidCastException : Unable to cast object of type 'Foo.Http.FooHttpClientProvider' to type 'Moq.IMocked`1[Foo.Http.FooHttpClientProvider]'.
Any ideas? Is this even possible?
Edit: Some extra information: the service I need to test gets injected with a FooHttpClientProvider. We use a global Mock with Autofac that registers the services we need. Since I can't pass the provider as a parameter, I can't instantiate a new Mock for FooHttpClientProvider and pass it to my service as a parameter; I need to set it up in the global mock. This further complicates things.
The code of the service looks something like this:
private readonly FooHttpClientProvider _client;
public FooService(
FooHttpClientProvider fooClient)
{
_client = fooClient("HttpClient");
}
public async Task<OutputDto> GetAsync(Request request)
{
var accessToken = await _AuthService.GetAccessTokenAsync();
try
{
var response =
await ExecuteGet<OutputDto>(
$"{FooConfig.BaseUrl}someEntpoint{GetQueryParams(request)}", accessToken);
return response;
}
catch(Exception ex)
{
//Exception handling
}
}
The service itself it's working correctly. The problem only arises when trying to mock it for unit testing.
Upvotes: 0
Views: 316
Reputation: 157
I was able to solve this. Turns out that mocking IHttpClient into my global Mock object, that alone was enough to get carried away to my DI container. Worked like a charm.
Upvotes: 0
Reputation: 247018
This is most likely an XY problem.
No need to mock the delegate. Use the actual delegate that returns a mock IHttpClient
[SetUp]
public void SetUp() {
Mock<IHttpClient> clientMock = new Mock<IHttpClient>();
//... set up the client mock to behave as needed
FooHttpClientProvider provider = (string name) => clientMock.Object;
//... use created delegate as needed with the subject under test
FooService subject = new FooService(provider);
}
Where the subject's constructor is invoked
//...
public FooService(FooHttpClientProvider fooClient) {
_client = fooClient("HttpClient");
//...
}
//...
the delegate created in the test will invoke and return the mocked IHttpClient
Upvotes: 1