是一种依赖另一种方法的代码味道吗?

jpo*_*poh 7 c# tdd unit-testing

我正在重构一个类,以便代码是可测试的(使用NUnit和RhinoMocks作为测试和隔离框架)并且发现我发现自己的方法依赖于另一个(即它取决于由其他方法创建的东西) ).类似于以下内容:

public class Impersonator
{
    private ImpersonationContext _context;

    public void Impersonate()
    {
        ...
        _context = GetContext();
        ...
    }

    public void UndoImpersonation()
    {
        if (_context != null)
            _someDepend.Undo();
    }
}
Run Code Online (Sandbox Code Playgroud)

这意味着要进行测试UndoImpersonation,我需要通过调用来设置它Impersonate(Impersonate已经有几个单元测试来验证它的行为).这对我来说闻起来很糟糕,但从某种意义上说,从调用此类的代码的角度来看它是有道理的:

public void ExerciseClassToTest(Impersonator c)
{
     try
     {
         if (NeedImpersonation())
         {
             c.Impersonate();
         }
         ...
     }
     finally
     {
         c.UndoImpersonation();
     }
}
Run Code Online (Sandbox Code Playgroud)

如果我没有尝试编写单元测试UndoImpersonation并且发现自己必须通过调用其他公共方法来设置测试,我就不会这样做了.那么,这是一种难闻的气味,如果是这样,我该如何解决呢?

pax*_*blo 9

代码气味必须是我在编程世界中遇到的最模糊的术语之一.对于一群以自己的工程原理而自豪的人来说,它在不可测量的垃圾方面排名靠前,并且作为无用的措施,就像程序员效率每天的LOC一样.

无论如何,这是我的咆哮,谢谢你的倾听:-)

要回答您的具体问题,我不认为这一个问题.如果您测试具有前置条件的内容,则需要确保为给定的测试用例首先设置了前置条件.

其中一个测试应该是在没有先设置前置条件的情况下调用它时发生的情况 - 它应该优先失败或者如果调用者没有这样做则设置它自己的前置条件.


sle*_*ske 8

好吧,有一点上下文要讲,看起来像_someDepend应该在构造函数中初始化.

在实例方法中初始化字段对我来说是一个很大的问题.一个类一旦构建就应该完全可用(即所有方法都可以工作); 所以构造函数应该初始化所有实例变量.请参阅Ward Cunningham维基中有关单步构造的页面.

在实例方法中初始化字段的原因很糟糕,主要是因为它对如何调用方法施加了隐式排序.在您的情况下,TheMethodIWantToTest将根据是否首先调用DoStuff来执行不同的操作.这通常不是你班级用户所期望的,所以这很糟糕:-(.

也就是说,有时这种耦合可能是不可避免的(例如,如果一个方法获取诸如文件句柄之类的资源,则需要另一种方法来释放它).但即便如此,也应该在一种方法中处理.

如果没有更多背景,那么适用于您的案例很难说清楚.