2008-10-10 83 views
6

说我有一个如何用最终方法去嘲笑一个类?

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

现在我有

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

B类我怎么会去的单元测试这种方法的A类? foo()是最终的原因是因为我们不希望我们的扩展A的类改变它的功能。但同时要真正对单元测试方法进行单元测试,我不希望它触及并运行实际的A.foo()方法。

有没有办法去删除最后一个关键字,并添加注释沿@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)); 
    } 
} 

这是frickin很酷还是什么?

+0

从大小写判断,这必须是Java。 – jop 2008-10-10 09:14:05

+0

你能告诉我们你用什么语言(看起来像java)?一些答案可能是语言依赖的,也可以告诉我们你使用的是什么嘲笑框架 – Jean 2008-10-10 09:14:30

回答

6

你可以试试JMockit嘲笑库。

+0

看起来很有趣,我会检查出来,谢谢。 – Epaga 2008-10-10 09:20:46

0

我想删除“最终”,只是在评论“不要重写此方法!!”。如果你不能相信同事不遵循简单的指示,反正无望。

+0

...除了我们不只是谈论同事,因为客户可以使用我们的API ... – Epaga 2008-10-10 11:44:04

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()); 
    } 
}