对我正在测试另一种方法的方法进行单元测试是不好的做法吗?

时间:2013-05-24 14:34:41

标签: unit-testing language-agnostic

考虑您有以下方法:

public Foo ParseMe(string filepath)
{
    // break up filename
    // validate filename & extension
    // retrieve info from file if it's a certain type
    // some other general things you could do, etc

    var myInfo = GetFooInfo(filename);

    // create new object based on this data returned AND data in this method
}

目前我有GetFooInfo的单元测试,但我想我还需要为ParseMe构建单元测试。在这种情况下,你有两个方法返回两个不同的属性 - 并且它们中的任何一个的变化都可能破坏某些东西 - 是否应该为两者创建单元测试以确定输出是否符合预期?

我喜欢在谨慎方面犯错误,并且对于破坏事物更加谨慎,并确保以后的维护更容易,但我对在测试项目中添加非常类似的测试感到非常怀疑。这是不好的做法还是有办法更有效地做到这一点?

我将此标记为语言无关,但为了重要,我正在使用C#和NUnit - 另外,我在标题中看到了类似的帖子,但问题不同。对不起,如果已经询问过。

4 个答案:

答案 0 :(得分:6)

ParseMe看起来非常重要,无法进行单元测试。要回答您的确切问题,如果“您有两种方法可以返回两种不同的属性 - 并且其中任何一种更改都可能会破坏”,那么您应该绝对对它们进行单元测试

即使大部分工作都在GetFooInfo,您至少应该测试它实际上是否被调用。我对NUnit一无所知,但我知道在其他框架(比如RSpec)中你可以编写像GetFooInfo.should be_called(:once)这样的测试。

答案 1 :(得分:4)

测试调用另一个方法的方法是 不好的做法。事实上,这是一个很好的做法。如果你有一个方法调用另一个方法,它可能正在执行其他功能,应该进行测试。

如果你发现自己单元测试一个方法,该方法调用一个也经过单元测试的方法,那么你可能正在经历代码重用,这是一件好事。

答案 2 :(得分:3)

我同意@tsm - 绝对测试两种方法(假设两种方法都是公开的)。

这可能是方法或阶级做得过多的气味 - 违反单一责任原则。考虑进行Extract Class重构和解耦两个类(可能使用依赖注入)。这样你就可以独立测试这两个功能。 (也就是说,如果功能足够复杂,我只会这样做。这是一个判断电话。)

这是C#中的一个例子:

public interface IFooFileInfoProvider
{
    FooInfo GetFooInfo(string filename);
}

public class Parser
{
    private readonly IFooFileInfoProvider _fooFileInfoProvider;

    public Parser(IFooFileInfoProvider fooFileInfoProvider)
    {
        // Add a null check
        _fooFileInfoProvider = fooFileInfoProvider;
    }

    public Foo ParseMe(string filepath)
    {
        string filename = Path.GetFileName(filepath);
        var myInfo = _fooFileInfoProvider.GetFooInfo(filename);
        return new Foo(myInfo);
    }
}

public class FooFileInfoProvider : IFooFileInfoProvider
{
    public FooInfo GetFooInfo(string filename)
    {
        // Do I/O
        return new FooInfo();  // parameters...
    }
}

答案 3 :(得分:0)

包括我在内的许多开发人员采用合同方式编程。这要求您将每个方法都视为黑盒子。如果方法委托给另一个方法来完成它的任务并不重要,那么当你测试方法时。但是,您还应该将程序的所有大型或复杂部分作为单元进行测试。因此,您是否需要对GetFooInfo进行单元测试取决于该方法的复杂程度。