为什么我的单元测试对 switch 语句失败?
Why is my unit test failing for a switch statement?
您好,我正在尝试对以下内容进行单元测试并检查此 switch/case 语句是否有效:
DiagnosticsComponentFactory
class
private readonly IServiceProvider _serviceCollection;
public IComponent Create (string name)
{
switch (name)
{
case BoardItemComponent.TypeName:
return _serviceCollection.GetService<BoardItemComponent>();
default:
throw new NotSupportedException();
}
}
我的BoardItemComponent
class:
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 语句并识别出这是正确的情况,但它仍然是 returns null。
根据我分享的内容(抱歉,我知道这些代码片段中的名称在没有上下文的情况下是模糊的),我的单元测试失败有什么明显的原因吗?我是 C# 单元测试的新手。
根据您的评论,您指出该组件已注册为
services.AddScoped<IComponent, BoardItemComponent>();
提供商知道 IComponent
接口,但要求 BoardItemComponent
实现
_serviceCollection.GetService<BoardItemComponent>();
如果提供者在明确请求时不知道如何解析 BoardItemComponent
,则以上内容将 return null
。
注册实现
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();
}
}
}
您好,我正在尝试对以下内容进行单元测试并检查此 switch/case 语句是否有效:
DiagnosticsComponentFactory
class
private readonly IServiceProvider _serviceCollection;
public IComponent Create (string name)
{
switch (name)
{
case BoardItemComponent.TypeName:
return _serviceCollection.GetService<BoardItemComponent>();
default:
throw new NotSupportedException();
}
}
我的BoardItemComponent
class:
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 语句并识别出这是正确的情况,但它仍然是 returns null。
根据我分享的内容(抱歉,我知道这些代码片段中的名称在没有上下文的情况下是模糊的),我的单元测试失败有什么明显的原因吗?我是 C# 单元测试的新手。
根据您的评论,您指出该组件已注册为
services.AddScoped<IComponent, BoardItemComponent>();
提供商知道 IComponent
接口,但要求 BoardItemComponent
实现
_serviceCollection.GetService<BoardItemComponent>();
如果提供者在明确请求时不知道如何解析 BoardItemComponent
,则以上内容将 return null
。
注册实现
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();
}
}
}