使用Rhino Mocks来模拟私有对象调用

sla*_*dau 1 .net c# integration-testing unit-testing rhino-mocks

所以我只是习惯于嘲笑东西.我在这里有这个私有变量:

private CoreDataContext _coreDataManager;
Run Code Online (Sandbox Code Playgroud)

在这堂课上:

public class RatesControlReport
        : Chatham.Panda.Batch.ProcessDefinition.BatchProcess
Run Code Online (Sandbox Code Playgroud)

这个类有一个void我想要测试的方法CheckSwaptionVols(DateTime runDate).

在我测试的第一部分中,我可以实例化主类:

RatesControlReport ratesControlReportProcess;
            ratesControlReportProcess = new RatesControlReport();
Run Code Online (Sandbox Code Playgroud)

基本上我想打这个电话:

ratesControlReportProcess.CheckSwaptionVols(DateTime.Now);
Run Code Online (Sandbox Code Playgroud)

但是,此方法使用私有变量,如下所示:

System.Data.Linq.ISingleResult<CheckSwaptionVols> swaptionStatusResult = _coreDataManager.CheckSwaptionVols(this._runDate);
Run Code Online (Sandbox Code Playgroud)

我希望能够传入此变量的模拟版本并返回我自己的指定,System.Data.Linq.ISingleResult<CheckSwaptionVols>以便测试可以继续而不依赖于DB.

我该怎么做?

Ama*_*hus 5

嗯,这取决于您实例化CoreDataContext的位置.如果这是在静态上下文中构造的,或者在构造函数中构造,则实际上没有办法为它创建模拟.这就是为什么在对象内实例化依赖关系通常被认为是不好的做法.您需要做的是提供一些依赖注入方法.这可以像重载的构造函数一样简单:

public RatesControlReport(CoreDataContext context)
{
    _coreDataManager = context;
}
Run Code Online (Sandbox Code Playgroud)

......如果你绝望的话,甚至是内部方法:

internal void InjectContext(CoreDataContext context)
{
    _coreDataManager = context;
}
Run Code Online (Sandbox Code Playgroud)

但是,一般来说,在构造RateControlReport时始终提供CodeDataContext对象被认为是最佳做法.这将把数据访问与业务逻辑分开,这将允许您更有效地对两个类进行单元测试.