如何对高依赖性方法进行单元测试?

时间:2011-12-19 20:17:01

标签: unit-testing junit

这里的单元测试概念相当新。我正在使用Java(JUnit),但这实际上是一个适用于任何类型的单元测试的问题。

说我有多个对象:

  • Widget
  • Foo
  • Fizz
  • Buzz

他们都在同一个包里。我们只是说Widget有一个run()方法,如下所示:

public void run() {
    Foo foo = new Foo(true, 1);
    Fizz fizz = FizzFactory.getInstance(Widget.class);
    Buzz buzz = getBuzz();

    int someData = fizz.process(buzz);
    foo.execute(someData);
}

因此,我们在run()内部调用了几个对象(及其方法)。一个人如何实际进行单元测试(“嘲弄”或“剔除”FooFizzBuzz)此方法而不会将灰色线划分为集成测试?

2 个答案:

答案 0 :(得分:2)

如果您正在进行静态调用以在方法中创建对象,那么您可能“做错了”。请注意,构造函数只是一种特殊的静态方法。

Misko Hevery在此主题上有很多非常好的帖子。

如果您希望能够测试您的课程,您需要能够通过测试模拟或存根来交换您的“业务逻辑”。你可以通过确保构造函数不做实际工作,而只是设置在其他地方构造的对象。

如果我要重构这个是可测试的,我会有这样的事情:

public class X {
  public X(FooFactory ff , FizzFactory fz, BuzzFactory bf) {
      _fooFactory = ff;
      _fizzFactory = fz;
      _buzzFactory = bf;
  }

  public void run() {
    Foo foo = _fooFactory.newFoo(true,1); 
    Fizz fizz = _fizzFactory.getInstance(Widget.class);
    Buzz buzz = _buzzFactory.getBuzz();

    int someData = fizz.process(buzz);
    foo.execute(someData);
  }
}

使用上面的工厂(或模拟行为的子类),你将X的测试仅限于它所调用的方法。您可以设置run方法的期望并测试它们,但不必处理fizz.process,比如连接到DB。

请注意,此处没有太多发生,没有分支,所以测试会相当简单。不在构造函数中调用new或者创建对象的静态方法的技巧应该继续。

在查找有关此信息时,一个好的关键字是Dependency Injection

答案 1 :(得分:0)

我个人认为,在这种情况下,你有单独的测试

Foo(bool, int)
 FizzFactory.getInstance
getBuzz()
fizz.process()

foo.execute

run()是上述所有方法的集成。