标题: Mocking with Jmockit [打印本页] 作者: lijingcheng3359 时间: 2009-11-25 14:20 标题: Mocking with Jmockit JMockit 是用以帮助开发人员编写测试程序的一组工具和API,该项目完全基于 Java 5 SE 的 java.lang.instrument 包开发,内部使用 ASM 库来修改Java的Bytecode。
When writing Unit Tests, it's often necessary to mock classes. There are several good frameworks to do this, such as EasyMock. This works fine in most cases, but it's possible to run into problems when using certain designs.
EasyMock (the same is true for most other mocking frameworks) can only mock public, non static or final methods. In most cases this is not a problem, it will fit most designs. It can be a problem however if you have code that uses, for example, a lot of static methods. It might be an option to refactor this (a lot of static methods might be an indication of bad design), but what if you use classes from external libraries?
JMockit is a small framework that can help out in such cases. It allows you to dynamically replace methods with new definitions. This is based on the Java 1.5 Instrumentation framework. The cool thing about JMockit is that it works with almost every design. It allows you to redefine private, static and final methods. Even no-arg constructors can be redefined.
At the project i'm currently working on we had some trouble figuring out what can and what can't be redefined, and how the method definitions should look like. I've written a small class and a JUnit testcase that redefines all possible methods from the class under test.
EasyMock等众多的mock框架仅能mock一些public,non static or final的方法,在大多数情况下这并没有什么问题,他可以处理大多数的问题,但是当测试的代码包含了一些静态方法,可能就让问题变得难以解决,有一种选择即是重构他(过多的静态方法可能预示着这并不是一个很好的设计),但是当你使用外部引用库所提供的方法,问题又该如何解决呢?
JMockit是一个能帮我们解决以上问题的轻量级框架,他允许你动态的改变已有的方法,这主要基于java 1.5的Instrumentation框架,这样便可以使得JMockit能够适应几乎所有的设计。他允许你重定义private,static and final方法,甚至是no-arg constructors都能够并轻易的重定义。
/**
* Public methods can be replaced
*/
public void testReplacePublic() {
assertEquals("Replaced public method", mockedClass.publicMethod());
}
/**
* Protected methods can be replaced.
* The replacement method should be declared public however
*/
public void testReplaceProtected() {
assertEquals("Replaced protected method", mockedClass.protectedMethod());
}
/**
* Package accessable methods can be replaced
* The replacement method should be declared public however
*/
public void testReplaceDefault() {
assertEquals("Replaced default method", mockedClass.defaultMethod());
}
/**
* Private methods can be replaced
* The replacement method should be declared public however
*/
public void testReplacePrivate() {
assertEquals("Replaced private method", mockedClass
.methodThatUsesPrivateMethod());
}
/**
* Non-default constructors can be replaced
* Your mock definition must have a default constructor however
*/
public void testReplaceConstructor() {
assertEquals(null, mockedClass.getMemberToSet());
}
/**
* Default constructors <b>can't</b> be replaced
*/
public void testReplaceDefaultConstructor() {
mockedClass = new ClassToMock();
assertEquals("Member set by original constructor", mockedClass
.getMemberToSet());
}
/**
* Static initializers <b>can't</b> be replaced
*/
public void testReplaceStaticBlock() {
assertEquals("Static initialized", mockedClass.getStaticMember());
}
}作者: 月上百合 时间: 2009-11-25 15:59
做白盒测试的吗?哎,偶看不懂作者: lijingcheng3359 时间: 2009-11-25 17:53 标题: 回复 2# 的帖子