我是否需要测试帮助/设置方法?

时间:2009-06-17 02:48:56

标签: unit-testing refactoring

所以我有一个类似于以下内容的辅助方法:

private D GetInstanceOfD(string param1, int param2)
{
    A a = new A();
    B a = new B();
    C c = new C(a,b, param1);

    return new D(c, param2);
}

这只是一个方便的帮助方法,我可以调用它来获取我需要的特定对象,然后记住我需要连接哪些依赖项来获取我需要的对象。

我的第一个问题是:应该测试这些方法吗?我想要测试这些类型的方法的唯一原因是确保使用正确的依赖关系并正确设置。

如果第一个问题的答案是肯定的,那么我的第二个问题是:怎么样?我目前正在使用NUnit和RhinoMocks,并试图弄清楚这个方法必须如何重构才能测试(好吧,这样的东西是否应该被测试!);依赖注入显然在这里不起作用,因为这个方法实际上创建了依赖项!

或者使用这种方法做坏事,我应该做以下事情:

D d = new (new C(new A(), new B(), "string"), 1024);

5 个答案:

答案 0 :(得分:3)

要回答您的第一个问题,是的,您应该测试此方法。测试此方法所需的工作量比编写整个帖子要少得多,并且可以验证运输代码。

就如何取决于您打算采用何种方法而言。假设函数的合理行为

,您可以测试以下内容
  • 如果我为第一个参数传递null会怎么样?
  • 如果我传递第二个参数的负数会怎样?
  • 在您期望的情况下,GetInstanceOfD是否实际返回D?
  • D是否具有给定输入的正确值。
  • 如果C,A和B实例可以访问它们怎么样?

答案 1 :(得分:2)

当你遇到这样的问题时,要记住的一件好事是让事情变得微不足道

设置方法必须是微不足道的。拆解方法需要微不足道。帮助方法可能非常重要 - 如果他们有自己的测试集。

如果您的单元测试本身变得如此复杂,需要来测试它们,那么你做错了。

答案 2 :(得分:1)

首先,该方法是私有的,因此,通常我会说直接对该方法可能不需要进行测试。即使它是实际代码的辅助方法,而不是测试的帮助程序,您可能只想通过公共接口间接测试它。

其次,如果你想测试它 - 或许无论如何 - 你应该考虑使用工厂来创建对象,而不是直接实例化对象。使用工厂和接口,将允许您抽象出依赖关系。只需将工厂注入包含此方法的类的构造函数中,并将其用作此方法中的属性即可创建正确的对象。如果你走这条路,你也可能会发现工厂也是逻辑创建D的地方。

如果代码是生产代码,这绝对是我要采取的方向。示例如下:

public class ObjectFactory 
{
     public virtual A CreateA() { return new A(); }
     public virtual B CreateB() { return new B(); }
     public virtual C CreateC( string str ) { return new C( CreateA(), CreateB(), str );
     public virtual D CreateD( string str, int num )
     {
         return new D( CreateC( str ), num );
     }
}


public class Foo
{
    private ObjectFactory ObjectFactory { get; set; }

    public Foo() : this(null) { }
    public Foo( ObjectFactory factory )
    {
         this.ObjectFactory = factory ?? new ObjectFactory();
    }

    public void Bar()
    {
        D objD = this.ObjectFactory.CreateD( param1, param2 );
    }
}

[TestMethod]
public void TestBar()
{
     var factory = MockRepository.GenerateMock<ObjectFactory>();
     var d = MockRepository.GenerateMock<D>();
     factory.Expect( f => f.CreateD( "abc", 10 ) ).Return( d );

     var foo = new Foo( factory );

     foo.Bar();

     factory.VerifyAllExpectations();
     d.VerifyAllExpectations();
}

答案 3 :(得分:1)

您应该测试此方法。你应该测试它,因为它可能会失败;一个XP格言测试可能破坏的所有内容

现在,这并不意味着你必须为它创建新的测试;它可以通过其他方法间接测试。如果它在重构期间被提取,那么它可能已经过测试。

如果需要,测试它的一种方法是将它提取到一个helper类中,它不是私有的,并将它分成几个函数以便能够注入依赖项。

//--- don't write this, you'll probably regret it ;o)
D d = new (new C(new A(), new B(), "string"), 1024);

答案 4 :(得分:0)

private方法通常表明它们不需要直接测试,因为您将测试使用这些private方法的方法。

该方法感觉它属于工厂或构建器类,而不是私有方法。如果将实例化代码隐藏为私有方法,它将无法优雅地测试。