考虑您有以下方法:
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 - 另外,我在标题中看到了类似的帖子,但问题不同。对不起,如果已经询问过。
答案 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
进行单元测试取决于该方法的复杂程度。