了解知识

因为近来一直在java上进行开发,在单元测试上,公司一直都采用JUnit和Jmock来进行,近来公司想把groovy和gmock引进来做单元测试,所以这段时间一直在看groovy和gmock这2个开源项目,到现在,已经有了一个初步的认识,下面就谈一下自己比较简单的想法吧。
Groovy是一个基于Java虚拟机的敏捷动态语言,可以作为 Java 的补充,它提供了更简单、更灵活的语法,其核心功能包括本地集合、内置正则表达式和闭包,(呵呵,闭包,好东西,看来有不少人讨厌java那个难看的匿名类做法;Groovy支持单元测试和mock,可以简化测试,其提供的GroovyTestCase继承了JUnit的TestCase
GMock则是一个专注于单元测试的优秀项目,提供GMockTestCase继承了JUnit的TestCase,并提供了更简练的mock方法,功能更加强大
比较jmock,groovy.mock,gmock,从简练程度来说gmock应该更理想,并且gmock比其他2种mock提供的功能更加强大

在单元测试上,groovy提供了采用map和clousre(闭包)来替代mock,在测试上也多了一种选择,下面通过一个例子来看一下几种不同的做法

这个例子是测试同 InteractivevoteService.delVote()方法(删除一个投票),这个方法中调用了CommentService.deleteAllPost()方法(删除评论)
1 java+jmock
public class InteractiveVoteServiceTest extends TestCase {
private InteractiveVoteService interactivevoteService;
private Mockery context = new Mockery() {
{
setImposteriser(ClassImposteriser.INSTANCE);
}
};
void setUp() {
//数据准备
interactivevoteService = new InteractiveVoteService()
}

public void test_delVote() {
final CommentService commentService = context
.mock(CommentService.class);

context.checking(new Expectations() {
{
oneOf(commentService).deleteAllPost(1);
}
});
interactivevoteService.setCommentService(commentService);

Vote vote = interactivevoteService.getVoteById(1);
assertNotNull(vote);

interactivevoteService.delVote(1);

Vote vote = interactivevoteService.getVoteById(1);
assertNull(vote);

context.assertIsSatisfied();
}
}
2、groovy+gmock
public class groovy_interactiveVoteServiceTest extends GMockTestCase{
private interactivevoteService
void setUp() {
//数据准备
interactivevoteService = new InteractiveVoteService()
}

void test_delVote() {
def commentService = mock(CommentService)
commentService.deleteAllPost(1).returns()
play{
interactivevoteService.setCommentService(commentService)

def vote = interactivevoteService.getVoteById(1)
assertNotNull(vote)

interactivevoteService.delVote(1)

vote = interactivevoteService.getVoteById(1)
assertNull(vote)
}

}
}

3 groovy闭包替代mock
public class groovy_interactiveVoteServiceTest extends GroovyTestCase{
private interactivevoteService
void setUp() {
//数据准备
interactivevoteService = new InteractiveVoteService()
}

void test_delVote() {
def delete={relate_id-> }
def commentService = [delete_all_post:delete]
interactivevoteService.setCommentService(commentService as CommentService)

def vote = interactivevoteService.getVoteById(1)
assertNotNull(vote)

interactivevoteService.delVote(1)

vote = interactivevoteService.getVoteById(1)
assertNull(vote)
}
}

上面的例子过于简单,可能并不能看出那个更好,在书写上gmock比jmock更加简练,至于closure和gmock,简单的可以用closure实现,复杂的对象替代可以采用gmock,毕竟gmock提供了运行的次数控制等功能,

说一下目前碰到的问题
groovy目前没有太强大的编辑器,虽然有eclipse的插件,但并不理想,特别是debug时,竟然不能step into方法里面,也可能是我没有配好,方法被反射掉了。
不过如果用groovy+gmock来做unit test还是比较理想的,至少可以先用gmock来取代jmock,也就是java+gmock也是可以的,因为研究时间还短,如果有什么不对的地方,可以给我留言指正。
groovy:http://groovy.codehaus.org/
gmock:http://gmock.org/ 

标签: Groovy
扩展知识