前陣子工作實在是太忙了,寫了很多很爛的code出來,然後效能很差,依賴很多,分層也不夠清晰,讓我想到之前在御諾時就有實踐過的TDD,當時我說的一口好code,說TDD可以幫助架構、重構,有助於在爛code出現時提前嗅到它的味道,但從御諾離職後我就沒再寫過單元測試了,ㄏㄏ。
之前在接案公司時是說寫單元測試會不統一,有人有寫有人沒寫,不好跟客戶交代,換到現在尋頂時則是專案太大,開發進度太趕,我就有點懶得寫了,再加上一開始項目其實有很多Dependency不存在我們這邊,存在伺服器那,寫單元測試的意願就直線下降了
直到最近寫了一坨爛code被K得滿頭包,決定要來解決一下這個問題,但在剛開始時就遇到一個問題,項目的@Dubbo無法被SpringBoot的@Mock給mock掉
1
2
3
4
5
| public class UserController {
@DubboReference
UserDubboService userDubboService;
}
|
1
2
3
4
5
6
7
8
| @RunWith(MockitoJUnitRunner.class)
@Slf4j
public class UserControllerTest {
@InjectMocks
UserController userController;
@Mock //這個會拋出null point exception
UserDubboService userDubboService;
}
|
這問題在GitHub上也有人反映
spring-boot-test @MockBean 对 dubbo-reference 失效
後來試過很多方式,比如說把@Autowired加在UserDubboService上面,或是把DubboServiceInterface加上@Component註解都沒辦法完成,最後是使用了反射(Reflection)去反向注入這個Bean進去
Code如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| @RunWith(MockitoJUnitRunner.class)
@Slf4j
public class UserControllerTest {
@InjectMocks
UserController userController;
//@Mock 不用在透過Mockito去注入測試依賴
UserDubboService userDubboService;
@Before
public void setUp() throws IllegalAccessException, NoSuchFieldException {
userDubboService = Mockito.mock(UserDubboService.class);
// 使用反射注入 glUserService
Field field = userController.getClass().getDeclaredField("userDubboService");
field.setAccessible(true);
field.set(userController, userDubboService);
}
}
|
就可以在呼叫userController時,去mock掉@DubboReference的bean了