Я пытаюсь запустить некоторые юнит-тесты и сталкиваюсь с проблемой, которая, я уверен, проистекает из недопонимания об автопроводке.У меня есть класс модульного тестирования, в котором я пытаюсь использовать @Autowired
на контроллере MockMvc и REST - оба из которых заканчиваются нулевым.
Я видел, как некоторые источники пытаются объяснить, почему это может(включая этот пост More of Less и полезный пост 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: Ожидается, что фактический не будет нулевым
Хотя, что любопытно, когда я создал новый проект Gradle на Java и импортировал мой пример кода из этого поста вэто, controllerNotNull()
проходит.
И testStoreSomething()
приводит к
java.lang.NullPointerException в com.example.sandbox.rest.ManagerControllerTest.testStoreSomething (ManagerControllerTest.java:46)
И здесь кроется вопрос: что я неправильно понимаю?Что я делаю неправильно?Я могу удалить @Autowired
из контроллера и просто создать его с помощью new ManagerController()
, но у меня остается проблема MockMvc.
ManagerController.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);
}
}
Manager.java
public class Manager {
private final Storage storage;
public Manager(Storage storage) {
this.storage = storage;
}
public void storeSomething(String str) {
storage.store(str);
}
}
Storage.java
public interface Storage {
void store(String str);
}
StringStorage.java
public class StringStorage implements Storage {
Map<String, String> stringMap;
@Override
public void store(String str) {
stringMap.put(str, str);
}
}
Application.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"
}