楠木軒

微服務項目(Spring Cloud,Dubbo)如何自測?

由 納喇曉枝 發佈於 科技

前言

一個單體項目的自測還是很方便的。那如果是一個微服務項目,該如何自測呢?

畢竟一個方法中有可能調用好多服務,而且調用的服務有可能好沒寫好,如果等別人的項目寫好再開始聯調的話,中途可能會耗費很長時間,因為調用的服務和自己的服務都有可能出問題,只有在聯調的時候才能暴露出來。

那有沒有更簡潔的方法呢?

其實我們可以把我們調用的服務,期待返回的結果全mock出來,然後跑單測,就能保證我們自己這邊的服務沒有問題。

mock別人的返回很耗時間,不值得把?

並不需要所有的接口都mock,一些重要業務節點的方法mock一下就行了。可能第一次比較耗時間,但是後續改動,你只需要執行一下單測就行了,保證了接口的穩定性。所以説微服務的單測還是很有必要的

測試框架有很多,Junit,EasyMock,PowerMock,TestNG,DBUnit等。

建議重要的業務流程寫單測,使用Junit,EasyMock測試框架
假如業務類為A,單測類的命名方式為ATest,ATest類和A類的包結構保持一致,測試的方法名保持一致

IDEA快速生成Test類

所在類按快捷鍵
Win:Ctrl + Shift + T
Mac:⇧ + command + T

選中要單測的方法點擊OK即可

EasyMock

看名字就能看出來,PowerMock更強大,EasyMock比較簡單。我平時也是用EasyMock最後,就分享一下這個框架的使用

假如有一個ManageService,依賴另一個服務的UserService

@Service
publicclassManageService{
@Autowired
private UserService userService;
public String getUsername(){
return userService.getUsername();
}
publicbooleansaveUserInfo(UserInfo userInfo){
return userService.saveUserInfo(userInfo);
}
}
1234567891011121314

publicinterfaceUserService{
String getUsername();
booleansaveUserInfo(UserInfo userInfo);
}
1234

@Data
publicclassUserInfo{
private String name;
private Integer age;
}
12345

可以按照如下方式寫單測

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = AppConfig.class)
public class ManageServiceTest {
@Autowired
private ManageService manageService;
privateUserServiceuserService;
@Test
publicvoidgetUsername() throwsException {
// 創建mock對象
userService = EasyMock.createMock(UserService.class);
// 調用userService.getUsername()方法時,返回test
EasyMock.expect(userService.getUsername()).andReturn("test");
// 將mock好的userService設置到manageService中
Field userServiceField = manageService.getClass().getDeclaredField("userService");
userServiceField.setAccessible(true);
userServiceField.set(manageService, userService);
EasyMock.replay(userService);
// 開始測試manageService
String username = manageService.getUsername();
System.out.println(username);
assertEquals(username, "test");
}

@Test
public void saveUserInfo() throws Exception {
userService = EasyMock.createMock(UserService.class);
// 傳入任意的對象,都會返回true
EasyMock.expect(userService.saveUserInfo(EasyMock.anyObject())).andReturn(true);
Field userServiceField = manageService.getClass().getDeclaredField("userService");
userServiceField.setAccessible(true);
userServiceField.set(manageService, userService);
EasyMock.replay(userService);

boolean flag = manageService.saveUserInfo(EasyMock.anyObject());
System.out.println(flag);
assertTrue(flag);
}

}

上面的例子中我用了一個對象EasyMock.anyObject(),表示不管傳入的對象是啥,都會返回true,EasyMock中還有很多類似的方法。

EasyMock.anyBoolean();
EasyMock.anyString();
EasyMock.anyObject();

如果我想針對不同的參數,返回不同的結果,mock2次即可。假如userService有這樣一個方法getUsername(String param)。你期待傳入1,返回100。傳入2,返回200

EasyMock.expect(userService.getUsername(1)).andReturn(100);
EasyMock.expect(userService.getUsername(2)).andReturn(200);

注意,當你傳入1,2之外的數字,會報錯,因為框架並不知道應該返回啥。

專欄
Java面試通關100問
作者:Java識堂
19.9幣
364人已購
查看

【來源:Java識堂】

聲明:轉載此文是出於傳遞更多信息之目的。若有來源標註錯誤或侵犯了您的合法權益,請作者持權屬證明與本網聯繫,我們將及時更正、刪除,謝謝。 郵箱地址:newmedia@xxcb.cn