6

我有一个带有构造函数注入的控制器

@RestController
@RequestMapping("/user")
public class MainController {

    private final UserMapper userMapper; // autowired by constructor below

    public MainController(UserMapper userMapper) {
        this.userMapper = userMapper;
    }

    @RequestMapping("/getChannels")
    public String index() {
        LoginUser user = userMapper.getUserByName("admin");
        return "Channels: " + user.getChannels();
    }
}

这是一个运行良好的简单类。但是,当我尝试使用以下类运行 JUnit 测试时,出现错误。

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
public class MainControllerTest {

    private MockMvc mvc;
    private final UserMapper userMapper;

    public MainControllerTest(UserMapper userMapper) {
        this.userMapper = userMapper;
    }

    @Before
    public void setUp() throws Exception {
        mvc = MockMvcBuilders.standaloneSetup(new MainController(userMapper)).build();
    }

    ......

错误是:

java.lang.Exception: Test class should have exactly one public zero-argument constructor

我对上面的错误消息感到困惑,我怎么能用零参数构造函数注入 userMapper?我知道可以在 MainController 中为 userMapper 添加@Autowired,但是不建议使用字段注入。请任何人指导我一种适合构造函数注入和 MockMvc 测试的方法。谢谢。

4

3 回答 3

1

其他答案谈论使用注释,但在这里您的问题与使用注释没有任何关系。请记住,作为 spring 4.3+,您不需要为依赖项注释构造函数,请在此处查看更多信息

事实上,您不需要尝试在您的 Test 类 ( MainControllerTest) 中模拟构造函数注入。您只需要UserMapper在应用程序上下文中声明为 spring 组件,并且在您的测试类中,它将作为正在运行的应用程序自动注入到您的控制器中。

你的错误是什么意思:错误消息中的所有 Junit Test 类都应该有一个公共的零参数构造函数,这是因为在你的场景这样的情况下 Junit Test 套件不知道如何实例化 Test 类。

于 2017-03-19T08:38:33.147 回答
0

在现场使用@Autowire。不建议在生产代码中使用字段注入,因为它会使推理变得混乱(在哪里注入什么以及为什么注入)。但是测试环境(尤其是像这样的环境)很简单,所以不存在硬推理的陷阱。

@Autowired
private final UserMapper userMapper;

public MainControllerTest() { //remove me, implicit
}

此更改将解决问题,因为 jUnit 将具有它可以理解的构造函数,并且能够实例化测试类。

于 2017-03-19T08:35:49.087 回答
-3

您缺少构造函数@AutowiredMainController并始终使用构造函数注入来解决问题,如下所示:

@RestController
@RequestMapping("/user")
public class MainController {

    private final UserMapper userMapper;

    @Autowired
    public MainController(UserMapper userMapper) {
        this.userMapper = userMapper;
    }

    //add methods here
}

使用字段注入不是最佳实践,请查看此处了解更多详细信息。

此外,要解决此问题,您需要更新您的测试类,如下所示:

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
public class MainControllerTest {

    private MockMvc mvc;

    @Mock
    private UserMapper userMapper;

    @InjectMocks
    private MainController mainController = new MainController(userMapper);

    @Before
    public void setUp() throws Exception {
        MockitoAnnotations.initMocks(this);
        mvc = MockMvcBuilders.standaloneSetup(mainController)..build();
    }

    ......
}
于 2017-03-19T08:37:27.117 回答