如何重构以避免使用Shim?

时间:2013-10-22 22:43:26

标签: c# unit-testing microsoft-fakes shim

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

对于有问题的代码,我有一个具有属性和方法的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,我需要做一些额外的事情,所以我在我的测试方法中设置了一个Stub来做那些额外的事情:

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?有关系吗?

感谢。

1 个答案:

答案 0 :(得分:0)

这是一种情况,而不是使用填充程序或存根,我只是让方法返回一个布尔值来通知内部调用是否已经发生。

使用伪造的问题是你假设某个对象的某些方法被调用,测试不应该知道。测试应该是愚蠢的,只能看到代码的外部。与任何其他代码一样,测试不应该关心如何达到值,只是它正确

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

这是依赖注入的原则:一个方法不应该旋转并隐藏它的依赖关系;如果它依赖于一个对象,那么该对象应该可以自由地改变或被传入。作业的确切实现应该与execute方法无关,并且与命名一起暗示你不应该得到它对象并在同一个调用中执行它。