1

首先,我是 Quartz.net 和 Moq 的新手。

我正在尝试使用 Moq 对 Quartz.net Execute 方法进行单元测试。Execute() 在 IJob 接口中定义。Execute 方法需要一个 IJobExecutionContext 传递给它。

我创建了一个名为 RunItinerary 的新作业类,它继承自 IJob 接口。下面是我所拥有的一个例子。

public class RunItinerary : IJob
{
   public RunItinerary()
   {
   }

   public RunItinerary(IBFDatabase db) : base(db)
   {
   }

   public override void Execute(IJobExecutionContext context)
   {
     // magic happens
   }
}

下面是我的单元测试的一个例子。我尝试运行一个简单的单元测试都没有成功。这是我尝试过的测试示例。

var mockIJobExecutionContext = new Mock<IJobExecutionContext>();
var runItinerary = new RunItinerary();
runItinerary.Execute(mockIJobExecutionContext.Object);
mockIJobExecutionContext.VerifyAll();

以下是错误:(x 用于掩盖内部名称)

Test method xx.xxxxxx.xxxxxxxx.xxxJobs.UnitTest.RunItineraryTest.Execute_Success threw exception: 
xx.common.Data.Exceptions.DatabaseConfigurationSectionNotFoundException: JobDatabase
at xx.common.Data.Abstract.xxDatabase..ctor(String configSectionName) in xxDatabase.cs: line 39
at xx.windows.Scheduler.Data.JobDatabase..ctor(String configSectionName) in JobDatabase.cs: line 24
at xx.windows.Scheduler.Data.JobDatabase..ctor() in JobDatabase.cs: line 20
at xx.windows.Scheduler.Jobs.BaseJob..ctor() in BaseJob.cs: line 45
at xx.windows.Scheduler.xxxJobs.RunItinerary..ctor() in RunItinerary.cs: line 31
at xx.windows.Scheduler.xxxJobs.UnitTest.RunItineraryTest.Execute_Success() in RunItineraryTest.cs:
line 177

我相信我缺少的东西在 mockIJobExecutionContext.Setup(x => x.???????) 中,我只是无法弄清楚我需要用 .Setup() 做什么

我已经查看了有关单元测试此 Execute() 的类似发布问题,但示例代码没有明确的答案。

如果有人可以提供答案,您能否为此提供一个示例单元测试?

4

1 回答 1

0

似乎RunItinerary(您正在测试的类)在依赖于 时具有“默认”行为IBFDatabase,这似乎是新建一个具体类的实例JobDatabase。因为这是一个单元测试,所以JobDatabase可能是因为缺少配置(例如连接字符串等)而失败

JobDatabase.cs 中的 xx.windows.Scheduler.Data.JobDatabase..ctor():第 20 行

幸运的是,您似乎有一个替代RunItinerary构造函数允许您提供IBFDatabase依赖项:

var mockJobExecutionContext = new Mock<IJobExecutionContext>();
var mockBFDatabase = new Mock<IBFDatabase>();
// You may need to do the minimal required Setups on `mockBFDatabase` here
var runItinerary = new RunItinerary(mockBFDatabase.Object); // i.e. use the other ctor

runItinerary.Execute(mockIJobExecutionContext.Object);

mockJobExecutionContext.Verify(x => x.SomeMethod(someParam), Times.Once);
mockBFDatabase.Verify(x => x.FetchSomeData(theIdIAmExpecting), Times.Once);

尽管在将单元测试(和依赖注入)改造到遗留代码中以具有“回退”(如果没有提供注入的依赖项)将类与其依赖项耦合的“回退”是很常见的,但我建议您尝试尽快删除这些以消除与具体的耦合依赖项并将其替换为 IoC 容器管理策略 - 这样您可以 100% 确定您正在单元测试的代码确实是真正的生产代码。

于 2014-10-27T08:32:03.967 回答