Mockito Hello World
專案配置
IDE是Intellij IDEA,用gradle配置專案.
新建一個Java專案,gradle中需要有這個:
repositories { jcenter() } dependencies { testCompile "org.mockito:mockito-core:1.+" }
單元測試用JUnit 4,所以gradle檔案如下:
apply plugin: 'java' apply plugin: 'idea' sourceCompatibility = 1.5 version = '1.0' repositories { mavenCentral() jcenter() } dependencies { testCompile group: 'junit', name: 'junit', version: '4.11' testCompile "org.mockito:mockito-core:1.8.5" }
寫好之後在命令列執行:gradle idea
相關的包就會下載好,並出現在這裡:
Hello World程式
想著寫一個Hello World說明一下Mockito怎麼用,結果寫著寫著就寫複雜了.
先看程式碼:
package com.mengdd.examples.mockito; public class HelloWorld { private MyRobot mRobot; public MyRobot getRobot() { return mRobot; } public void setRobot(MyRobot robot) { this.mRobot = robot; } /** * This is the method we want to test. * When there is an robot, this method return the robot's information * otherwise, return some sorry text */ public String sayHello() { MyRobot robot = getRobot(); if (null != robot) { return robot.getSomeInfo(); } return "No robot here, sorry!"; } /** * MyRobot class */ public static class MyRobot { /** * Get some information from somewhere, the implementation may varies */ public String getSomeInfo() { return "Hello World -- From robot"; } } }
這段程式碼裡面包含了一個HelloWorld類和一個內部靜態類MyRobot(我的機器人).
HelloWorld中有一個方法叫sayHello(),是我們要測的方法.
它會判斷成員變數是否為空,不為空則呼叫其方法獲取一些資訊,否則返回一條提示資訊.
-------------------
這裡插播一下,關於內部類的介紹可以參見以前的一篇筆記:http://www.cnblogs.com/mengdd/archive/2013/02/08/2909307.html
內部靜態類和內部非靜態類可以類比:靜態成員變數和非靜態成員變數.
-------------------
測試類程式碼如下:
package com.mengdd.examples.mockito; import org.junit.Test; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; public class HelloWorldTest { @Test public void testSayHelloWhenThereIsRobot() throws Exception { // We want to test the sayHello() method in the class HelloWorld. // But we don't care about how MyRobot get its information.(We can treat it as external interface). // Maybe the robot rely on many complicated things.(Although it's simple in this case.) // And when the robot's actions change in the future, we don't need to change this test case. // We can mock the MyRobot's action to make it simple and just test whether sayHello() can do its own work. // Mock steps HelloWorld.MyRobot robot = mock(HelloWorld.MyRobot.class); // Mock MyRobot class String mockInfo = "some mock info"; when(robot.getSomeInfo()).thenReturn(mockInfo); // Set behavior for mock object // real object HelloWorld helloWorld = new HelloWorld();//This is the real objec we want to test helloWorld.setRobot(robot);//set the mock robot to real object // execute the target method we want to test String result = helloWorld.sayHello(); // assert the result is what we want to have assertThat(result, is(mockInfo)); } }
因為我們要測試的是HelloWorld的sayHello()方法是否能正常工作.
我們需要假定其中robot的行為是正常的(我們並不關心robot實際上做的工作,以及它怎麼做),所以這裡用到了mock.
比如如果機器人的實現中要傳送一個請求,我們這裡就是直接mock它得到的結果,而不是真的去發這個請求.
就好像準備好了所需要的所有外部條件,看sayHello()方法的表現是否能符合我們的預期.
為了全面起見,測試了sayHello()的另一種case,這裡沒有用到mockito.
@Test public void testSayHelloWhenThereIsNoRobot() throws Exception { HelloWorld helloWorld = new HelloWorld(); helloWorld.setRobot(null); String result = helloWorld.sayHello(); assertThat(result, is("No robot here, sorry!")); }
參考資料
Mockito at github: https://github.com/mockito/mockito