我正在測驗 ControllerAdvice 類,其中 EncodeUtil 是自動裝配的,當我使用 JUnit 測驗運行時,這總是被決議為 Null,通過 Spring Boot 應用程式運行時沒有問題,我在這里缺少什么?
@ControllerAdvice
public class Base64EncodedResponseBodyAdvice implements ResponseBodyAdvice<Object> {
@Autowired
private EncodeUtil encodeUtil;
@Override
public boolean supports(MethodParameter returnType,
Class<? extends HttpMessageConverter<?>> converterType) {
return true;
}
@Override
public Object beforeBodyWrite(Object body,
MethodParameter returnType,
MediaType selectedContentType,
Class<? extends HttpMessageConverter<?>> converterType,
ServerHttpRequest request,
ServerHttpResponse response) {
if(returnType.getMethod().getName().equalsIgnoreCase("doPNMImage"))
{
encodeUtil.encodeBase64(body);
response.getHeaders().add("ENCODE_TYPE", "Base64");
}
else return body;
}
}
這是我的 Junit 類,我有
@ExtendWith(SpringExtension.class)
@WebMvcTest(PNMImageController.class)
@AutoConfigureMockMvc
public class Base64EncodedResponseBodyAdviceTest {
@Mock
private EncodeUtil encodeUtil;
@InjectMocks
PNMImageController pnmImageController;
@BeforeEach
void init(){
MockitoAnnotations.initMocks(pnmImageController);
mockMvc = MockMvcBuilders.standaloneSetup(pnmImageController)
.setControllerAdvice(Base64EncodedResponseBodyAdvice.class)
.build();
}
@Test
public void getAuthorizeTest() throws Exception {
ReflectionTestUtils.setField(encodeUtil, "salt", SALT);
Mockito.when(this.encodeUtil.encodeBase64()).thenReturn(TEST_BASE64_STR);
mockMvc.perform(post("http://localhost:8080/image/doPNMImage"))
.andExpect(status().isOk())
.andExpect(content().string(TEST_BASE64_STR))
.andExpect(header().string("ENCODE_TYPE", "Base64"));
}
}
測驗失敗,出現 Nullpointer 例外
Request processing failed; nested exception is java.lang.NullPointerException: Cannot invoke "com.ylm.cnpl.core.util.EncodeUtil.encodeBase64(String)" because "this.encodeUtil" is null
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.NullPointerException: Cannot invoke "com.ylm.cnpl.core.util.encodeBase64(String)" because "this.encodeUtil" is null
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909)
uj5u.com熱心網友回復:
@WebMvcTest-javadoc :
使用此注釋將禁用完全自動配置,而是僅應用與 MVC測驗相關的配置(即@Controller、@ControllerAdvice、@JsonComponent、Converter/GenericConverter、Filter、WebMvcConfigurer 和 HandlerMethodArgumentResolver bean,而不是 @ Component 、@Service 或 @Repository bean )。
如果我們想EncodeUtil在我們的測驗中作為一個 bean:匯入(配置),配置/組件掃描它。
最簡單:使用
@SpringBootTest代替@WebMvcTest.為了保持測驗背景關系“苗條”,我們應該:
專門用于受災豆(S)A(主)配置和匯入他們進入測驗。
或者/和專門的“測驗”配置,最簡單的方法是:
@ExtendWith(SpringExtension.class) @WebMvcTest(PNMImageController.class) @AutoConfigureMockMvc public class Base64EncodedResponseBodyAdviceTest { @Configuration static class CustomTestConfig { @Bean EncodeUtil ... } ... }
如果我們要@InjectMocks作業,我們應該(嘗試)@MockBean,而不是@Mock... @Mock,@MockBean和Mockito.mock()之間的區別...... @Mock和@InjectMocks之間的區別...
在 彈簧測驗,我會使用: (org.springfr...)@MockBean和@Autowired!;)
uj5u.com熱心網友回復:
當您嘗試測驗一個控制器和 controllerAdvice 時,使用 @WebMvcTest(PNMImageController.class)
使用@WebMvcTest,您可以依靠 Spring 創建所需的控制器。您嘗試使用 @InjectMocks 創建第二個,但無法構建 Spring 嘗試構建的那個。
見@WebMvcTest javadoc
使用此注釋將禁用完全自動配置,而是僅應用與 MVC 測驗相關的配置(即@Controller、@ControllerAdvice、@JsonComponent、Converter/GenericConverter、Filter、WebMvcConfigurer 和 HandlerMethodArgumentResolver bean,而不是 @Component、@Service 或 @Repository bean )。
您需要EncodeUtil向 Spring提供。當您打算將其用作模擬時,要使用的正確注釋是 @MockBean
其次,您創建了一個 mockMvc 實體。沒有必要這樣做 - 你明確地寫了@AutoConfigureMockMvc,所以你可以將它自動連接到你的測驗中。事實上@WebMvcTest 是用@AutoConfigureMockMvc 注釋的,所以你在你的測驗中不需要它。@ExtendWith(SpringExtension.class) 也是一樣。
更新代碼
@WebMvcTest(PNMImageController.class)
public class Base64EncodedResponseBodyAdviceTest {
@MockBean
private EncodeUtil encodeUtil;
@Autowired
MockMvc mockMvc;
@Test
public void getAuthorizeTest() throws Exception {
// ReflectionTestUtils.setField(encodeUtil, "salt", SALT);
Mockito.when(this.encodeUtil.encodeBase64()).thenReturn(TEST_BASE64_STR);
mockMvc.perform(post("http://localhost:8080/image/doPNMImage"))
.andExpect(status().isOk())
.andExpect(content().string(TEST_BASE64_STR))
.andExpect(header().string("ENCODE_TYPE", "Base64"));
}
}
最重要的是:
- 在 encodeUtil 上設定 salt 欄位看起來很可疑。您不需要在模擬上設定欄位。
恕我直言,將您的測驗更改@SpringBootTest為不是要走的路:
SpringBootTest用于集成測驗,它將啟動您的整個應用程式。當然它會完成作業——你的控制器也會被旋轉,但你應該努力保持你的測驗盡可能精簡——只旋轉所需的控制器會讓你的測驗更快、更不脆弱。
uj5u.com熱心網友回復:
請添加@SpringBootTest更多:https : //docs.spring.io/spring-boot/docs/2.1.5.RELEASE/reference/html/boot-features-testing.html#boot-features-testing-spring-boot-應用程式,您需要指定加載@ContextConfiguration ( https://docs.spring.io/spring-boot/docs/1.4.0.M3/reference/htmlsingle/#boot-features-testing-spring-boot-應用程式檢測配置)
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/389332.html
上一篇:按鈕無法正常作業-JavaSpringThymeleaf
下一篇:正則運算式中前一行的回傳值
