C# 自定义AutoFixture中抽象类的构造函数输入

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

在尝试对服务方法进行单元测试时,它实现的基本抽象类构造函数包含2个参数。我想在使用Auto fixture调用服务时自定义这些参数

基本服务代码如下所示

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
。如果不能,也可以对该类型使用类似的方法