我正在测试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"));
}
}
测试失败与空指针异常
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)
请添加@SpringBootTest更多信息:https://docs.spring.io/spring-boot/docs/2.1.5.RELEASE/reference/html/boot-features-testing.html#boot-具有测试Spring Boot应用程序的功能,您需要指定要加载@ContextConfiguration的配置(https://docs.spring.io/spring-boot/docs/1.4.0.M3/reference/htmlsingle/#boot-功能测试spring启动应用程序(检测配置)
当您尝试测试一个控制器和controllerAdvice时,使用@WebMvcTest(PNMImageController.class)
通过@WebMvcTest,您可以依靠Spring来创建所需的控制器。您试图用@InjectMocks创建第二个,但无法构建Spring尝试构建的那个。
请参阅@WebMvcTest javadoc
使用此注释将禁用完全自动配置,而只应用与MVC测试相关的配置(即@Controller、@ControllerAdvice、@JsonComponent、Converter/GenericConverter、Filter、WebMVCConfiguer和HandlerMethodArgumentResolver bean,但不应用@Component、@Service或@Repository bean)。
您需要向Spring提供EncodeUtil
。由于您打算将其用作模拟,因此正确的注释是@MockBean
其次,创建mockMvc的一个实例。不需要这样做-您显式地编写了@AutoConfigureMockMvc,因此可以将其自动连接到测试中。事实上,@WebMvcTest是用@AutoConfigureMockMvc注释的,所以在测试中不需要它。@extendedwith(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"));
}
}
除此之外:
如果将您的测试更改为@SpringBootTest
不是一个好办法:SpringBootTest
用于集成测试,它将使您的整个应用程序加速。当然,这将完成工作-您的控制器也将被旋转,但您应该努力使测试尽可能精简-仅旋转所需的控制器将使您的测试更快、更不脆弱。
@WebMvcTest
-javadoc:
使用此注释将禁用完全自动配置,而只应用与MVC测试相关的配置(即@Controller、@ControllerAdvice、@JsonComponent、Converter/GenericConverter、Filter、WebMVCConfiguer和HandlerMethodArgumentResolver bean,但不应用@Component、@Service或@Repository bean)。
如果我们想在测试中把EncodeUtil
作为bean:导入(配置),配置/组件扫描它。
>
为了保持测试上下文“苗条”,我们应该:
>
为受影响的bean指定一个(主)配置
或/和专用的"测试"配置,最简单的:
@ExtendWith(SpringExtension.class)
@WebMvcTest(PNMImageController.class)
@AutoConfigureMockMvc
public class Base64EncodedResponseBodyAdviceTest {
@Configuration
static class CustomTestConfig {
@Bean
EncodeUtil ...
}
...
}
如果我们想要@InjectMocks
工作,我们应该(尝试)@MockBean
而不是@Mock
。。。@Mock、@MockBean和Mockito之间的区别。mock()。。。@Mock和@injectmock之间的区别。。。
在spring测试中,我会使用:(org.springfr…)<代码>@MockBean和@Autowired
!;)
我尝试使用以下代码模拟我的Runtime.getRuntime(): 但是我有以下错误:
如何测试使用JdbcTemplate和SimpleJDBCall的repository类,如下所示 这就是我尝试过的 下面是测试代码和存储库代码,我使用的是Spring Boot最新版本junit5和mockito。我已经尝试了下面的解决方案,但可以让它工作 带Spring JdbcTemplate的SimpleJDBCall的Mockito 下面是存储库代码@repository public
我有一个应用程序,公开Websocket/SockJS/Stomp服务器endpoint,并想运行一个JUnit测试,运行客户端(JavaSTOMP客户端,也来自Spring)对它,以测试发送功能。 我有一个测试,如 在这里,我从 https://github.com/jhalterman/concurrentunit 中使用了Water,其效果基本上是将测试的主线程延迟到辅助线程调用reachi
另一个,如果我有另一个应用程序使用相同的使用者组,所有的分区会被重新分配到该应用程序吗?
当我运行junit测试时,控制台打印此异常: 基本测试对象如下 而 JUnit 方法就像这样: 我的项目是JavaEE项目,使用maven管理lib,使用spring-manage-beans。 我的开发环境是: Mac OS X Yosetime 10.10.4 EclipseJavaEE IDE for Web Developers(版本:Mars Release(4.5.0)) Maven插
我想尝试嵌入式数据库测试我的DAO对象在spring应用程序。 在应用程序上下文中,我有以下标记: 我的JUnit测试类需要使用这个bean: 一切正常(创建了“DataSourceEmbedded”bean),但当我试图在PartnerDAOTest类中自动调用它们时,spring抛出了以下异常: testSavePartner(Sandbox.PartnerDaoTest):创建名为“Sand