测试现场注入VS构造函数注入

时间:2017-11-09 13:30:34

标签: java unit-testing spring-mvc dependency-injection mockito

我尝试在控制器中通过构造器注入替换场注入,因为它似乎是最佳实践。 当我运行应用程序时,它适用于两种解决方案。

我的问题在于控制器的单元测试。 我为Controller使用现场注入编写了测试类。 它工作正常。 现在我用constuctor注入替换场注入。测试失败。

这是我的初始控制器(带场注入):

@Controller
public class DashboardController {

    @Autowired
    private MyService myService;

    @RequestMapping("/")
    public String index(Model model) {
        MyPojo myPojo = myService.getMyPojo();
        model.addAttribute("myPojo", myPojo);
        return "dashboard";
    }

}

现在新的Controller(带有constuctor注入):

@Controller
public class DashboardController {

    private final MyService myService;

    @Autowired
    public DashboardController(MyService myService) {
        this.myService = myService;
    }

    @RequestMapping("/")
    public String index(Model model) {
        MyPojo myPojo = myService.getMyPojo();
        model.addAttribute("myPojo", myPojo);
        return "dashboard";
    }

}

测试类:

@RunWith(SpringRunner.class)
@ContextConfiguration(classes = {MyApplication.class})
@WebAppConfiguration
@TestPropertySource(locations = "classpath:/application.properties")
public class DashboardControllerUnitTests {

    @InjectMocks
    private DashboardController dashboardController;

    @Mock
    private MyService myService;

    private MockMvc mockMvc;

    @Before
    public void setup() {
        MockitoAnnotations.initMocks(this);
        mockMvc = MockMvcBuilders
                .standaloneSetup(dashboardController)
                .build();
    }

    @Test
    public void getDashboard() throws Exception {
        doReturn(new MyPojo()).when(myService).getMyPojo();
        mockMvc.perform(get("/"))
                .andDo(print())
                .andExpect(status().isOk())
                .andExpect(model().attribute("myPojo", equalTo(new MyPojo()))); // The test fail here
        verify(myService).getMyPojo();
    }

}

如果我使用我的Controller的初始版本运行测试,它可以正常工作。 但是如果我使用新版本的Controller(使用构造函数注入)运行相同的测试,则myPojo为null并且测试失败。

似乎mockito如果是构造函数注入就不会模拟服务。 你知道为什么我有这个问题以及如何解决它吗?

1 个答案:

答案 0 :(得分:2)

您需要将设置方法更改为以下内容:

@Before
public void setup() {
    dashboardController = new DashboardController(myService);
    mockMvc = MockMvcBuilders
            .standaloneSetup(dashboardController)
            .build();
}