我大部分时间都在使用EasyMock ,但是最近我和一些非常愿意使用Mockito的人一起工作。
我不打算在同一项目中使用两个框架来实现相同的目的,因此我采用了Mockito 。
因此,在过去的几个月中,我一直在使用Mockito ,这是我对两者的比较分析。
与我一起工作的人列举了使用Mockitio的测试可读性的原因,但是我对此有不同的看法。
假设我们要测试以下代码:
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30public class MyApp { MyService service; OtherService otherService; void operationOne() { service.operationOne(); } void operationTwo(String args) { String operationTwo = otherService.operationTwo(args); otherService.operationThree(operationTwo); } void operationThree() { service.operationOne(); otherService.operationThree("success"); } } class MyService { void operationOne() {} } class OtherService { public String operationTwo(String args) { return args; } public void operationThree(String operationTwo) {} }
现在,让我使用EasyMock和Mockito为此类编写一个简单的测试用例。
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42public class MyAppEasyMockTest { MyApp app; MyService service; OtherService otherService; @Before public void initialize() { service = EasyMock.createMock(MyService.class); otherService = EasyMock.createMock(OtherService.class); app = new MyApp(); app.service = service; app.otherService = otherService; } @Test public void verifySimpleCall() { service.operationOne(); EasyMock.replay(service); app.operationOne(); EasyMock.verify(service); } } public class MyAppMockitoTest { MyApp app; MyService service; OtherService otherService; @Before public void initialize() { service = Mockito.mock(MyService.class); otherService = Mockito.mock(OtherService.class); app = new MyApp(); app.service = service; app.otherService = otherService; } @Test public void verifySimpleCall() { app.operationOne(); Mockito.verify(service).operationOne(); } }
这是一个非常简单的测试,我必须说Mockito更具可读性。
但是根据经典的测试方法,Mockito测试并不完整。
我们已经验证了我们正在寻找的电话,但是如果明天我通过添加一个服务电话来更改源代码,则测试不会中断。
复制代码
1
2
3
4void operationOne() { service.operationOne(); service.someOtherOp(); }
现在,这使我感到测试不够好。
但值得庆幸的是,Mockito提供了verifyNoMoreInteractions ,可用来完成测试。
现在,让我为MyApp类编写一些测试。
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61public class MyAppEasyMockTest { @Test public void verifyMultipleCalls() { String args = "one"; EasyMock.expect(otherService.operationTwo(args)).andReturn(args); otherService.operationThree(args); EasyMock.replay(otherService); app.operationTwo(args); EasyMock.verify(otherService); } @Test(expected = RuntimeException.class) public void verifyException() { service.operationOne(); EasyMock.expectLastCall().andThrow(new RuntimeException()); EasyMock.replay(service); app.operationOne(); } @Test public void captureArguments() { Capture<String> captured = new Capture<String>(); service.operationOne(); otherService.operationThree(EasyMock.capture(captured)); EasyMock.replay(service, otherService); app.operationThree(); EasyMock.verify(service, otherService); assertTrue(captured.getValue().contains("success")); } } public class MyAppMockitoTest { @Test public void verifyMultipleCalls() { String args = "one"; Mockito.when(otherService.operationTwo(args)).thenReturn(args); app.operationTwo(args); Mockito.verify(otherService).operationTwo(args); Mockito.verify(otherService).operationThree(args); Mockito.verifyNoMoreInteractions(otherService); Mockito.verifyZeroInteractions(service); } @Test(expected = RuntimeException.class) public void verifyException() { Mockito.doThrow(new RuntimeException()).when(service).operationOne(); app.operationOne(); } @Test public void captureArguments() { app.operationThree(); ArgumentCaptor capturedArgs = ArgumentCaptor .forClass(String.class); Mockito.verify(service).operationOne(); Mockito.verify(otherService).operationThree(capturedArgs.capture()); assertTrue(capturedArgs.getValue().contains("success")); Mockito.verifyNoMoreInteractions(service, otherService); } }
这些是一些实际的测试场景,我们想要声明参数,异常等。如果我查看并比较使用EasyMock编写的测试和使用Mockito进行的测试,我倾向于觉得这两个测试在可读性上都是相同的,但它们都没有一个更好的任务。
EasyMock中大量的期望和返回调用使测试不可读,并且Mockito的verify语句通常会影响测试的可读性。
根据Mockito的书verifyZeroInteractions,verifyNoMoreInteractions不应在您编写的每个测试中使用,但是如果我将它们排除在测试范围之外,则我的测试还不够好。
此外,在测试中,所有事情都应在开发人员的控制之下,即交互如何发生以及交互如何发生。
在EasyMock中,这方面更明显,因为开发人员必须在他的代码中放下所有这些交互,但是在Mockito中,框架负责所有交互,而开发人员只关心它们的验证(如果有)。
但是,这可能会导致测试场景,其中开发人员不受所有交互的控制。
Mockito具有像JunitRunner这样的好东西,可用于创建具有所有必需依赖项的Mocks。
这是删除一些基础结构代码的好方法,并且EasyMock也应该有一个。
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15@RunWith(MockitoJUnitRunner.class) public class MyAppMockitoTest { MyApp app; @Mock MyService service; @Mock OtherService otherService; @Before public void initialize() { app = new MyApp(); app.service = service; app.otherService = otherService; } }
结论:
由于我已经使用了这两个框架,因此我认为,除了简单的测试用例之外,EasyMock和Mockito都导致可读性相同的测试用例。
但是EasyMock对于单元测试更好,因为它迫使开发人员控制事物。
由于其假设和考虑,Mockito将这种控制隐藏在地毯下,因此不是一个好选择。
但是Mockito提供了某些非常有用的功能(例如junitRunner,调用链接),而EasyMock的下一个版本中应该有一个。
参考: 到目前为止 ,我们的JCG合作伙伴 Rahul Sharma 使用EasyMock或Mockito在The road…博客博客中。
翻译自: https://www.javacodegeeks.com/2012/08/using-easymock-or-mockito.html
最后
以上就是陶醉月亮最近收集整理的关于使用EasyMock或Mockito的全部内容,更多相关使用EasyMock或Mockito内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复