从测试用例调用控制器时,使用自动连接组件测试控制器为空

Ste*_*art 1 java junit spring autowired spring-boot

我有一个控制器

@RestController
public class Create {

    @Autowired
    private ComponentThatDoesSomething something;

    @RequestMapping("/greeting")
    public String call() {
        something.updateCounter();
        return "Hello World " + something.getCounter();
    }

}
Run Code Online (Sandbox Code Playgroud)

我有该控制器的组件

@Component
public class ComponentThatDoesSomething {
    private int counter = 0;

    public void updateCounter () {
        counter++;
    }

    public int getCounter() {
        return counter;
    }
}
Run Code Online (Sandbox Code Playgroud)

我也对我的控制器进行了测试。

@RunWith(SpringRunner.class)
@SpringBootTest
public class ForumsApplicationTests {

    @Test
    public void contextLoads() {
        Create subject = new Create();
        subject.call();
        subject.call();
        assertEquals(subject.call(), "Hello World 2");
    }

}
Run Code Online (Sandbox Code Playgroud)

当控制器调用 时,测试失败something.updateCounter()。我得到一个NullPointerException. 虽然我知道可以添加@Autowired到构造函数中,但我想知道是否有任何方法可以对@Autowired字段执行此操作。如何确保@Autowired字段注释在我的测试中有效?

Ser*_*man 5

Spring 不会自动连接您的组件,因为您使用new而不是 Spring 来实例化您的 Controller ,因此 Component 不会被实例化

SpringMockMvc 测试检查它是否正确:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public class CreateTest {
    @Autowired
    private WebApplicationContext context;

    private MockMvc mvc;

    @Before
    public void setup() {
        mvc = MockMvcBuilders
                .webAppContextSetup(context)
                .build();
    }

    @Test
    public void testCall() throws Exception {
        //increment first time
        this.mvc.perform(get("/greeting"))
                .andExpect(status().isOk());
        //increment secont time and get response to check
        String contentAsString = this.mvc.perform(get("/greeting"))
                .andExpect(status().isOk()).andReturn()
                .getResponse().getContentAsString();
        assertEquals("Hello World 2", contentAsString);
    }
}
Run Code Online (Sandbox Code Playgroud)