C#:Moq System.NotSupportedException:无法将佣金问题应用于组件,因为它似乎是无目标代理

C#: Moq System.NotSupportedException : Can not apply commission concerns to component because it appears to be a target-less proxy

我正在尝试模拟服务,并在单元测试中收到以下错误。如何解决?这个错误是什么意思?可能与 await/async 有关系吗?

services.AddSingleton(a =>
{
    var mock = new Mock<IUserResolverService>();
    mock.Setup(b => b.GetUser()).Returns(5);
    return mock.Object;
});

System.NotSupportedException : Can not apply commission concerns to component Common.Services.IUserResolverService_175a16cd-d798-4fbd-b343-1ba0eb5e0ad6 because it appears to be a target-less proxy. Currently those are not supported. DefaultKernel.ResolveComponent(IHandler handler, Type service, IDictionary additionalArguments, IReleasePolicy policy) IKernelInternal.Resolve(Type service, IDictionary arguments, IReleasePolicy policy) ScopedWindsorServiceProvider.GetServiceInternal(Type serviceType, Boolean isOptional) line 55

更多代码资料:

    private async Task<IServiceProvider> GetProvider()
    {
        var services = new ServiceCollection();
        services.AddSingleton(new Mock<ISharedServicesApiClient>().Object);
        services.AddSingleton(new Mock<IAddressValidator>().Object);
        services.AddSingleton(new Mock<IAddressValidationService>().Object);

        services.RegisterMappingProfiles(
            new PropertyManagementDataMappingProfile(),
            new ApplicationServicesMappingProfile()
        );
        services.AddSingleton(a =>
        {
            var mock = new Mock<IUserResolverService>();
            mock.Setup(b => b.GetUser()).Returns(5);
            return mock.Object;
        });

        services.AddDbContext<PropertyContext>(
            a => a.UseInMemoryDatabase("TestDb").UseQueryTrackingBehavior(QueryTrackingBehavior.TrackAll),
            ServiceLifetime.Singleton);

        services.AddDbContext<AuditablePropertyContext>(
            a => a.UseInMemoryDatabase("TestDb").UseQueryTrackingBehavior(QueryTrackingBehavior.TrackAll),
            ServiceLifetime.Singleton);
        services.AddSingleton<DbContext, AuditablePropertyContext>();

        services.AddSingleton<DbContext, PropertyContext>();
        services.AddSingleton<IAddressAppService, AddressAppService>();
        services.AddSingleton<IAddressRepository, AddressRepository>();
        services.AddSingleton<IPartyContactRepository, PartyContactRepository>();
        services.AddSingleton<IPartyMailingAddressRepository, PartyMailingAddressRepository>();

        var provider = services.GetServiceProvider();
        var db = provider.GetRequiredService<PropertyContext>();
        await db.AddTestData();
        return provider;
    }

    [Fact]
    public async Task AddNewAddressAlternateAddTest()
    {
        var provider = await GetProvider();
        var manager = provider.GetRequiredService<IAddressAppService>();
        var request =
            SitusAndPartyAddressDataSeed.GetSingleApnRequestForAdd(AddressType.Alternate);
        var result = await manager.UpdatePartyAndSitusAddresses(request);
        // new AddressId is 3
        Assert.True(result.Body == NewAddressId);

根据一些推理对 "hunch" 进行跟进,您正在为 IUserResolverService 的模拟实例设置一个单例,但正如所写的那样,您正在使用委托而不是唯一地组合和返回该模拟对象只需创建已完成模拟的单个实例并注册它,而不是像注册所有其他模拟一样。鉴于同步和异步操作的混合,看起来您的测试导致 Moq 与对象的 lifecycle/creation 斗争。

如果我们改变这个:

services.AddSingleton(a =>
{
     var mock = new Mock<IUserResolverService>();
     mock.Setup(b => b.GetUser()).Returns(5);
     return mock.Object;
 });

为此:

var mock = new Mock<IResolverService();
mock.Setup(b => b.GetUser()).Returns(5);
services.AddSingleton(mock.Object);

然后您将传入模拟的实际单个实例,这可能会解决导致问题的任何问题,无论是生命周期还是后期绑定(或其他问题,但是嘿)。