在 .Net Core 3.1 中使用 Moq 模拟委托时出现问题

Problem mocking delegate with Moq in .Net Core 3.1

我在模拟 returns 和 IHttpClient 的代表时遇到问题。这是客户的要求,我不能更改实现。

代码看起来像这样:

代表:

namespace Foo.Http
{
    public delegate IHttpClient FooHttpClientProvider(string name);
}

测试class:

[SetUp]
public void SetUp()
{
    Mock<FooHttpClientProvider>().Setup(x => x("HttpClient")).Returns(Mock<IHttpClient>().Object);
}

当我这样做时,出现以下异常:

System.InvalidCastException : Unable to cast object of type 'Foo.Http.FooHttpClientProvider' to type 'Moq.IMocked`1[Foo.Http.FooHttpClientProvider]'.

有什么想法吗?这甚至可能吗?

编辑: 一些额外信息:我需要测试的服务被注入了 FooHttpClientProvider。我们使用带有 Autofac 的全局 Mock 来注册我们需要的服务。由于我无法将提供程序作为参数传递,因此我无法为 FooHttpClientProvider 实例化一个新的 Mock 并将其作为参数传递给我的服务;我需要在全球模拟中设置它。这使事情更加复杂。

服务代码如下所示:

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
        }
}

服务本身运行正常。只有在尝试模拟它进行单元测试时才会出现问题。

这很可能是 XY problem

无需模拟委托。使用 return 模拟 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);
}

调用主体的构造函数的地方

//...

public FooService(FooHttpClientProvider fooClient) { 
   
    _client = fooClient("HttpClient");

    //...
}

//...

在测试中创建的委托将调用并且 return 模拟的 IHttpClient

我能够解决这个问题。事实证明,将 IHttpClient 模拟到我的全局 Mock 对象中,仅此一项就足以带走我的 DI 容器。工作得很好。