为什么我的单元测试未能通过switch语句?

时间:2019-11-27 15:12:15

标签: c# .net unit-testing dependency-injection nunit

嗨,我正在尝试对以下内容进行单元测试,并检查此switch / case语句是否有效:

DiagnosticsComponentFactory

private readonly IServiceProvider _serviceCollection;

public IComponent Create (string name)
{
    switch (name)
    {
        case BoardItemComponent.TypeName:
            return _serviceCollection.GetService<BoardItemComponent>();
        default:
            throw new NotSupportedException();
    }
}

我的BoardItemComponent班:

public class BoardItemComponent
{
    public const string TypeName = "name";

    public BoardItemComponent(IConfigurationRepository configurationRepository) : base(configurationRepository)
    {

    }
}

BoardItemComponent派生自IComponent,并在我的 Startup.cs 文件中如下添加:

services.AddScoped<IComponent, BoardItemComponent>();

我的单元测试:

[Test]
public void GetComponent_GivenComponentFactory_ExpectBoardComponent()
{
    var serviceCollection = new ServiceCollection();
    ComponentFactoryRegistration.Register(serviceCollection);
    var factory = new DiagnosticsComponentFactory(serviceCollection.BuildServiceProvider());
    var component = factory.Create("name");
    Assert.IsNotNull(component);
}

调试单元测试时,component null ,尽管它遵循所有正确的步骤。它会正确进入switch case语句并识别出正确的大小写,但是仍返回 null

从我分享的内容(和歉意,我知道这些代码段中的名称含糊其词,没有上下文),是否有任何明显的原因导致我的单元测试失败?在C#中进行单元测试时,我是新手。

1 个答案:

答案 0 :(得分:1)

根据您的评论,您表示该组件已注册为

services.AddScoped<IComponent, BoardItemComponent>();

提供者知道IComponent接口,但要求实现BoardItemComponent

_serviceCollection.GetService<BoardItemComponent>();

如果提供者在明确请求时不知道如何解决null,则以上内容将返回BoardItemComponent

注册实施

services.AddScoped<BoardItemComponent>();

,您还可以使用工厂委托将其与抽象相关联

services.AddScoped<IComponent>(sp => sp.GetRequiredService<BoardItemComponent>());

现在应该能够相应地进行隔离测试

[Test]
public void GetComponent_GivenComponentFactory_ExpectBoardComponent() {
    //Arrange
    var serviceCollection = new ServiceCollection();
    serviceCollection.AddScoped<BoardItemComponent>();
    serviceCollection.AddScoped<IConfigurationRepository>(sp => Mock.Of<IConfigurationRepository>());

    var factory = new DiagnosticsComponentFactory(serviceCollection.BuildServiceProvider());

    //Act
    var component = factory.Create(BoardItemComponent.TypeName);

    //Assert
    Assert.IsNotNull(component);
}

现在表明将来可能还会有更多实施。

举个例子

services.AddScoped<BoardItemComponent>();
services.AddScoped<AnotherItemComponent>();

然后可以重构工厂

public class DiagnosticsComponentFactory {    
    private readonly IServiceProvider services;

    public DiagnosticsComponentFactory (IServiceProvider services) {
        this.services = services;
    }

    public IComponent Create (string name) {
        switch (name) {
            case BoardItemComponent.TypeName:
                return services.GetRequiredService<BoardItemComponent>();
            case AnotherItemComponent.TypeName:
                return services.GetRequiredService<AnotherItemComponent>();
            default:
                throw new NotSupportedException();
        }
    }
}