![](/img/trans.png)
[英]Autowired MockMvc is null with JUnit 5 and Spring boot
[英]Spring - How to properly use @Autowired to prevent controller / MockMvc from being null?
我正在嘗試運行一些單元測試並遇到一個問題,我確信該問題源於對自動裝配的誤解。 我有一個單元測試類,我試圖在其中使用@Autowired
在 MockMvc 和 REST 控制器上——這兩個最終都是空的。
我已經看到一些來源試圖解釋為什么會發生這種情況(包括這篇更多的更少的帖子和一個有用的StackOverflow 帖子,它給了我一些見解,但並沒有完全幫助我解決我的問題)。
以下是我為重現此問題而制作的示例項目中的相關源代碼。
ManagerControllerTest.java
@RunWith(SpringRunner.class)
@WebMvcTest(ManagerController.class)
public class ManagerControllerTest {
@Autowired
private MockMvc mockMvc;
@MockBean
private Manager manager;
@Autowired
private ManagerController controller;
@Test
public void controllerNotNull() throws Exception {
assertThat(controller).isNotNull();
}
@Test
public void testStoreSomething() throws Exception {
String path = "/manager/store-something/";
MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get(path)
.characterEncoding("UTF-8")
.contentType(MediaType.APPLICATION_JSON);
MvcResult result = mockMvc.perform(builder).andReturn();
assertEquals(HttpStatus.CREATED, result.getResponse().getStatus());
}
}
controllerNotNull()
測試結果
java.lang.AssertionError:期望實際不為空
雖然奇怪的是,當我用 Java 創建一個新的 Gradle 項目並將我的示例代碼從這篇文章導入到其中時, controllerNotNull()
通過了。
和testStoreSomething()
結果
java.lang.NullPointerException 在 com.example.sandbox.rest.ManagerControllerTest.testStoreSomething(ManagerControllerTest.java:46)
問題就在這里:我誤解了什么? 我究竟做錯了什么? 我可以從控制器中刪除@Autowired
並使用new ManagerController()
實例化它,但我留下了 MockMvc 問題。
管理器控制器.java
@Controller
@RequestMapping(value = "/manager/")
public class ManagerController {
Manager manager = new Manager(new StringStorage());
@PostMapping(value = "store-something")
private ResponseEntity<?> storeSomething(String str) {
manager.storeSomething(str);
return new ResponseEntity<>(CREATED);
}
}
管理器
public class Manager {
private final Storage storage;
public Manager(Storage storage) {
this.storage = storage;
}
public void storeSomething(String str) {
storage.store(str);
}
}
存儲.java
public interface Storage {
void store(String str);
}
字符串存儲
public class StringStorage implements Storage {
Map<String, String> stringMap;
@Override
public void store(String str) {
stringMap.put(str, str);
}
}
應用程序.java
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
build.gradle已從原始帖子(使用 JUnit4)中編輯,但問題仍然存在。
repositories {
jcenter()
}
apply plugin: 'java'
apply plugin: 'eclipse'
dependencies {
compile group: 'org.springframework.boot', name: 'spring-boot-starter-web', version: '2.0.0.RELEASE'
compile group: 'org.springframework.boot', name: 'spring-boot-starter-tomcat', version: '2.0.0.RELEASE'
testCompile group: 'org.springframework.boot', name: 'spring-boot-starter-test', version: '2.0.0.RELEASE'
testImplementation 'org.junit.jupiter:junit-jupiter-api:4.0.0'
testImplementation 'org.junit.jupiter:junit-jupiter-params:4.0.0'
testCompile group: 'org.mockito', name: 'mockito-core', version: '2.17.0'
testCompile group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: "4.0.0"
testCompile group: 'org.junit.platform', name: 'junit-platform-launcher', version: "1.3.1"
}
@RestController
@RequestMapping(value = "/manager")
public class ManagerController {
@Autowired
Manager manager;
@PostMapping(value = "/store-something")
private ResponseEntity<?> storeSomething(String str) {
manager.storeSomething(str);
return new ResponseEntity<>(CREATED);
}
}
@Component
public class Manager {
@Autowired
private Storage storage;
public void storeSomething(String str) {
storage.store(str);
}
}
public interface Storage {
void store(String str);
}
@Service
public class StringStorage implements Storage {
Map<String, String> stringMap = new HashMap<>();
@Override
public void store(String str) {
stringMap.put(str, str);
}
}
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
測試類:
@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class ApplicationTest {
@Autowired
private MockMvc mockMvc;
@Test
public void shouldReturnDefaultMessage() throws Exception {
this.mockMvc.perform(post("/manager/store-something")).andDo(print()).andExpect(status().isOk())
.andExpect(content().string(containsString("Hello World")));
}
}
將注釋 AutoConfigureMockMvc 添加到您的測試類
@RunWith(SpringRunner.class)
@AutoConfigureMockMvc
public class ManagerControllerTest {
@Autowired
private MockMvc mockMvc;
@MockBean
private Manager manager;
@Autowired
private ManagerController controller;
@Test
public void controllerNotNull() throws Exception {
assertThat(controller).isNotNull();
}
@Test
public void testStoreSomething() throws Exception {
this.mvc.perform(get("/manager/store-something/"))
.contentType(MediaType.APPLICATION_JSON)
.andExpect(status().isOk())
}
或者,您也可以將 TestRestTemplate 與 @SpringBootTest(webEnvironment= SpringBootTest.WebEnvironment.RANDOM_PORT) 一起使用
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.