C# 自定义AutoFixture中抽象类的构造函数输入
在尝试对服务方法进行单元测试时,它实现的基本抽象类构造函数包含2个参数。我想在使用Auto fixture调用服务时自定义这些参数 基本服务代码如下所示C# 自定义AutoFixture中抽象类的构造函数输入,c#,.net-core,abstract-class,mstest,autofixture,C#,.net Core,Abstract Class,Mstest,Autofixture,在尝试对服务方法进行单元测试时,它实现的基本抽象类构造函数包含2个参数。我想在使用Auto fixture调用服务时自定义这些参数 基本服务代码如下所示 public abstract class ServiceBase : IHostedService, IDisposable { private readonly CronExpression _expression; private readonly TimeZoneInfo _timeZoneInfo; protect
public abstract class ServiceBase : IHostedService, IDisposable
{
private readonly CronExpression _expression;
private readonly TimeZoneInfo _timeZoneInfo;
protected BaseService(string cronExpression, TimeZoneInfo timeZoneInfo)
{
_expression = CronExpression.Parse(cronExpression);
_timeZoneInfo = timeZoneInfo;
}
public abstract Task ExecuteTask(CancellationToken cancellationToken);
.
.
}
另一个服务继承自此基本抽象类
public class TestService : ServiceBase
{
public override async Task ExecuteTask(CancellationToken stoppingToken)
{
//Implementation here
}
}
在我的单元测试中,我调用ExecuteTask
函数,如下所示
Func<Task> executeAction = async () => await sut.ExecuteTask(A<CancellationToken>._);
executeAction.Should().NotThrow();
Func executeask=async()=>await sut.ExecuteTask(A.);
executeAction.Should().NotThrow();
AutoFixture
尝试将随机字符串传递给BaseService
类中的CronExpression
构造函数参数。问题在于CronExpression
必须采用特定的格式,否则在尝试解析它时会发生错误CronExpression.Parse(CronExpression)
如何为构造函数参数传递自定义值
提前感谢。AutoFixture不知道类的
字符串参数的域约束。这应该给出一个提示,可能这个类型不是类的最合适的参数。这是一个典型的例子
您可以将服务增强为直接接受封装这是一个CronExpression的类型:
protectedservicebase(CronExpression-CronExpression,TimeZoneInfo-TimeZoneInfo)
{
_cronExpression=cronExpression;
...
}
这样,可以保证BaseService
将被传递一个有效的CronExpression
。如果不是,则CronExpression
的创建将已经失败
您可能认为我们已经简单地转移了问题:现在如何告诉AutoFixture创建有效的CronExpression
将工作转移到构建CronExpression
的好处是,为创建有效的CronExpression
而进行的任何定制现在都可以用于需要它的任何其他类型。这将减少将来需要这种类型的测试的仪式。更不用说避免原始痴迷的所有其他好处了
关于告诉AutoFixture如何创建有效的CronExpression
,有许多选项。您可以直接注入一个有效的:
fixture.Inject(CronExpression.Parse(“myValidCronExpression”);
如果希望能够选择多个,可以使用ElementsBuilder
从有效值池中进行选择:
公共无效测试()
{
var fixture=新fixture();
fixture.Customizations.Add(新建ElementsBuilder(
新[]{“validExpr1”、“validExpr2”}
.Select(s=>CronExpression.Parse)
.ToArray())
...
}
通过创建ISpecimenBuilder
的实现,可以对该类型的创建进行最大程度的控制,我将在本回答中省略它。如果你想走这条路,这里和其他地方都有很多例子
对AutoFixture进行其中一项自定义后,sut的创建将起作用:
var sut=fixture.Create();
注意:我还没有测试AutoFixture的默认样本生成器是否可以直接实例化TimeZoneInfo
。如果不能,也可以对该类型使用类似的方法。AutoFixture不知道类的字符串参数的域约束。这应该给出一个提示,可能这个类型不是类的最合适的参数。这是一个典型的例子
您可以将服务增强为直接接受封装这是一个CronExpression的类型:
protectedservicebase(CronExpression-CronExpression,TimeZoneInfo-TimeZoneInfo)
{
_cronExpression=cronExpression;
...
}
这样,可以保证BaseService
将被传递一个有效的CronExpression
。如果不是,则CronExpression
的创建将已经失败
您可能认为我们已经简单地转移了问题:现在如何告诉AutoFixture创建有效的CronExpression
将工作转移到构建CronExpression
的好处是,为创建有效的CronExpression
而进行的任何定制现在都可以用于需要它的任何其他类型。这将减少将来需要这种类型的测试的仪式。更不用说避免原始痴迷的所有其他好处了
关于告诉AutoFixture如何创建有效的CronExpression
,有许多选项。您可以直接注入一个有效的:
fixture.Inject(CronExpression.Parse(“myValidCronExpression”);
如果希望能够选择多个,可以使用ElementsBuilder
从有效值池中进行选择:
公共无效测试()
{
var fixture=新fixture();
fixture.Customizations.Add(新建ElementsBuilder(
新[]{“validExpr1”、“validExpr2”}
.Select(s=>CronExpression.Parse)
.ToArray())
...
}
通过创建ISpecimenBuilder
的实现,可以对该类型的创建进行最大程度的控制,我将在本回答中省略它。如果你想走这条路,这里和其他地方都有很多例子
对AutoFixture进行其中一项自定义后,sut的创建将起作用:
var sut=fixture.Create();
注意:我还没有测试AutoFixture的默认样本生成器是否可以直接实例化TimeZoneInfo
。如果不能,也可以对该类型使用类似的方法