6

说我有A类

class A {
  final String foo() {
    // .. computing result, contacting database, whatever ..
    return "some computed value";
  }
  // ... and a bazillion other methods, some of them final.
}

现在我有B级

class B {
  String methodIWantToTest(A a) {
      String output = a.foo();
      // ... whatever this method does, e.g.:
      output += "_suffix";
      return output;
  }
}

我将如何对这种方法进行单元测试?原因foo()是最终的,因为我们不希望扩展 A 的类改变其功能。但是在真正对方法进行单元测试的同时,我不希望它伸出手来运行实际的A.foo()方法。

有没有办法,比如说,删除 final 关键字并添加注释@finalUnlessTest?你会推荐什么?将 A 重构为接口将非常非常困难,因为它是我们的中心类之一,并且不幸的是非常耦合。

编辑#1对不起,忘了提,我们说的是 Java。到目前为止,我们还没有使用模拟框架。

回答好,所以:哇。JMockit简直令人难以置信,在我看来,它是测试遗留代码的杀手级应用。令人难以置信的有用,尤其是在我的情况下。非常感谢!您基本上会为我的伪示例执行以下操作:

class AMock {
   final String foo() {
     return "myTestValue";
   }
}
class Test extends TestCase {
   A mockedA;
   B b;
   protected void setUp() {
      Mockit.redefineMethods( A.class, AMock.class );  // this "pipes" all mocked methods from A to AMock
      mockedA = new A();    // NOT new AMock()!!!
      b = new B();
   }
   public void testB() {
      assertEquals("myTestValue",mockedA.foo());
      assertEquals("myTestValue_suffix",b.methodIWantToTest(mockedA));
   }
}

这是他妈的酷还是什么?

4

3 回答 3

6

你可以试试JMockit模拟库。

于 2008-10-10T09:15:02.573 回答
0

我会删除“最终”并添加评论“不要覆盖此方法!!”。如果你不能相信同事不遵循简单的指示,那无论如何都是没有希望的。

于 2008-10-10T09:11:00.957 回答
0

以下代码也将允许您执行此操作。我并不是说这是一种好的做法,但它是匿名类的一个有趣的使用(滥用?)。

public class Jobber {

    public final String foo() {
        return fooFactory() ;
    }

    String fooFactory() {
        return "jobber" ;
    }


    public static void main(String[] args) {

        Jobber jobber = new Jobber() { String fooFactory() { return "prefix " + super.fooFactory() ;} } ;

        System.out.println(jobber.foo() );
    }
}
于 2008-10-13T09:05:38.350 回答