【问题标题】:Testing Field Injection VS Constructor Injection测试字段注入 VS 构造函数注入
【发布时间】:2017-11-09 13:30:33
【问题描述】:

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

我的问题在于我的控制器的单元测试。 我为使用字段注入的控制器编写测试类。 它工作正常。 现在我用构造函数注入替换字段注入。测试失败。

这是我的初始控制器(带有字段注入):

@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
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(使用构造函数注入)运行相同的测试,myPojo 为 null 并且测试失败。

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

【问题讨论】:

  • 您是否尝试过在MyService 上使用@MockBean 注释?并在DashboardController 上使用简单的@Autowired?并删除整个setup() 方法?

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


【解决方案1】:

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

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

【讨论】:

  • 谢谢,这行得通。我没想到要初始化控制器。
猜你喜欢
  • 1970-01-01
  • 2017-04-05
  • 2013-03-23
  • 2013-11-13
  • 2014-01-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多