jmockit

王朝百科·作者佚名  2010-08-24  
宽屏版  字体:   |    |    |  超大  

Mocking with Jmockit

JMockit 是用以帮助开发人员编写测试程序的一组工具和API,该项目完全基于 Java 5 SE 的 java.lang.instrument 包开发,内部使用 ASM 库来修改Java的Bytecode。

在单元测试中,经常需要进行一些mock操作。现在已经有了一些比较不错的框架在做这些事情,比如:EasyMck,他在大多数情况下运行良好,但是对于某些结构的设计却显得无能为力。

EasyMock等众多的mock框架仅能mock一些public,non static or final的方法,在大多数情况下这并没有什么问题,他可以处理大多数的问题,但是当测试的代码包含了一些静态方法,可能就让问题变得难以解决,有一种选择即是重构他(过多的静态方法可能预示着这并不是一个很好的设计),但是当你使用外部引用库所提供的方法,问题又该如何解决呢?

JMockit是一个能帮我们解决以上问题的轻量级框架,他允许你动态的改变已有的方法,这主要基于java 1.5的Instrumentation框架,这样便可以使得JMockit能够适应几乎所有的设计。他允许你重定义private,static and final方法,甚至是no-arg constructors都能够并轻易的重定义。

在实际的项目中有些方法可以重定义而有些不行,为了更好的说明如何对方法进行重定义,下面有一个简单的类和对应测试代码的demo,他尽可能考虑到了几乎所有的情况,供大家方便的学习。

ClassToMock :

publicclassClassToMock {

privateStringmemberToSet;

privatestaticStringstaticMember;

static{

staticMember= "Static initialized";

}

publicClassToMock() {

this.memberToSet= "Member set by original constructor";

}

publicClassToMock(String value) {

this.memberToSet= "Member set by original constructor";

}

publicString publicMethod() {

return"Original public method";

}

protectedString protectedMethod() {

return"Original protected method";

}

String defaultMethod() {

return"Original default method";

}

publicString methodThatUsesPrivateMethod() {

returnprivateMethod();

}

privateString privateMethod() {

return"Original private method";

}

publicString getMemberToSet() {

returnmemberToSet;

}

publicString getStaticMember() {

returnstaticMember;

}

}

ClassToMockTest :

importjunit.framework.TestCase;

importmockit.Mockit;

publicclassClassToMockTestextendsTestCase {

privateClassToMock mockedClass;

publicstaticclassReplacement {

static{

}

publicReplacement() {

}

publicReplacement(String test) {

}

publicString publicMethod() {

return"Replaced public method";

}

publicString protectedMethod() {

return"Replaced protected method";

}

publicString defaultMethod() {

return"Replaced default method";

}

publicString privateMethod() {

return"Replaced private method";

}

}

protectedvoidsetUp()throwsException {

Mockit.redefineMethods(ClassToMock.class, Replacement.class);

mockedClass =newClassToMock("test");

}

protectedvoidtearDown()throwsException {

Mockit.restoreAllOriginalDefinitions();

}

/**

* Public methods can be replaced

*/

publicvoidtestReplacePublic() {

assertEquals("Replaced public method", mockedClass.publicMethod());

}

/**

* Protected methods can be replaced.

* The replacement method should be declared public however

*/

publicvoidtestReplaceProtected() {

assertEquals("Replaced protected method", mockedClass.protectedMethod());

}

/**

* Package accessable methods can be replaced

* The replacement method should be declared public however

*/

publicvoidtestReplaceDefault() {

assertEquals("Replaced default method", mockedClass.defaultMethod());

}

/**

* Private methods can be replaced

* The replacement method should be declared public however

*/

publicvoidtestReplacePrivate() {

assertEquals("Replaced private method", mockedClass

.methodThatUsesPrivateMethod());

}

/**

* Non-default constructors can be replaced

* Your mock definition must have a default constructor however

*/

publicvoidtestReplaceConstructor() {

assertEquals(null, mockedClass.getMemberToSet());

}

/**

* Default constructors <b>can't</b> be replaced

*/

publicvoidtestReplaceDefaultConstructor() {

mockedClass =newClassToMock();

assertEquals("Member set by original constructor", mockedClass

.getMemberToSet());

}

/**

* Static initializers <b>can't</b> be replaced

*/

publicvoidtestReplaceStaticBlock() {

assertEquals("Static initialized", mockedClass.getStaticMember());

}

}

 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
© 2005- 王朝百科 版权所有