繁体   English   中英

如何使用MockMvc的构造函数注入来测试控制器

[英]How to test a controller with constructor injection by MockMvc

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

@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测试的方法。 谢谢。

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

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

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

在场上使用@Autowire。 在生产代码中不建议使用现场注入,因为它会使推理变得混乱(注入的位置和原因)。 但测试环境(尤其是那些像这样的环境)很简单,因此存在难以推理的缺陷。

@Autowired
private final UserMapper userMapper;

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

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

您为MainController构造函数丢失@Autowired并始终使用构造函数注入,如下所示解决此问题:

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

    private final UserMapper userMapper;

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

    //add methods here
}

使用现场注入不是最佳做法,请在此处查看更多详细信息。

另外,要解决此问题,您需要更新Test类,如下所示:

@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();
    }

    ......
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM