嗨,我正在尝试对以下内容进行单元测试,并检查此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#中进行单元测试时,我是新手。
答案 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();
}
}
}