0

我对单元测试很陌生,并且正在探索 Microsoft Fakes 框架 - 主要是因为它是免费的,它允许我使用 Emulators 包轻松模拟 SharePoint 对象。我在 SO 和其他地方看到过各种提及 Shims 是邪恶的,我或多或少地理解为什么。我没有得到的是如何在一种特定情况下避免它们 - 换句话说,“我应该如何重构我的代码以避免不得不使用垫片?”

对于有问题的代码,我有一个 JobProcessor 对象,它具有属性和方法,其中一些是私有的,因为它们只能从公共 Execute 方法调用。我想测试一下,当调用 Execute 并且有一个 Job 可用时,它的 Process 方法被调用,因为我需要做一些额外的日志记录。

以下是相关代码:

//in system under test - JobProcessor.cs

private IJob CurrentJob { get; set; }

public void Execute()
{
   GetJobToProcess();  //stores Job in CurrentJob property if found
   if (ShouldProcessJob){
       CurrentJob.ProcessJob();
   }
}

如果从测试中调用 ProcessJob,我需要做一些额外的事情,所以我在我的测试方法中设置了一个存根来做这些额外的事情:

StubIJob fakeJob = new StubIJob(){
    ProcessJob = () =>{
        //do my extra things here
    }

};

我正在其他地方测试 ProcessJob 方法本身,所以我不在乎它除了我的额外内容之外什么都不做。据我了解,我现在需要设置一个 Shim 以让 JobProcessor(我的测试系统)中的私有方法 GetJobsToProcess 返回我的假作业,以便调用我的存根方法:

processor = new JobProcessor();
ShimJobProcessor.AllInstances.GetJobToProcess = (@this) =>{
   var privateProcessor = new PrivateObject(processor);
   privateProcessor.SetProperty("CurrentJob", fakeJob);  //force my test Job to be processed so the Stub is used
};

在这种情况下,我应该如何避免使用 Shim?有关系吗?

谢谢。

4

1 回答 1

0

在这种情况下,我只是让方法返回一个布尔值来通知内部调用是否发生,而不是使用 shim 或存根。

使用假货的问题是您假设调用了某个对象的某些方法,而测试不应该知道。测试应该是愚蠢的,并且只看到代码的外部。与任何其他代码一样,测试不应该关心值是如何达到的,只要它是正确的即可。

但是,您的代码还有另一个问题。您得到一些未知对象并在同一范围内使用它。您应该从 Execute 中删除对 GetJobToProccess 的调用。

这就是依赖注入的原则:一个方法不应该启动并隐藏它的依赖;如果它依赖于一个对象,则该对象应该可以自由更改或传入。作业的确切实现与执行方法无关,并且与命名一起意味着您不应该得到那个对象并在同一个调用中执行它。

于 2013-10-29T22:37:44.893 回答