如何对以 ModelAndView 作为参数的方法进行单元测试和模拟

How to unit test and mock a method that takes a ModelAndView as Parameter

我有一个名为

的 i18n 属性文件
MessagesBundle_en.properties

invalidresourceBundle = Default locale English
invalidUserName = UserName cannot be null or empty or blank string

我有一个名为 ParameterVerify 的 class 来验证参数。

public class ParameterVerify {

    public void verifyParameters(String userName, ModelAndView modelAndView, ResourceBundle resourceBundle) {

        if (resourceBundle == null) {
            resourceBundle = ResourceBundle.getBundle("MessagesBundle", Locale.ENGLISH);
        }

        if (!(verifyParameter(userName))) {
            modelAndView.addObject("invalidUserName", resourceBundle.getString("invalidUserName"));
        }
    }

    private boolean verifyParameter(final String parameter) {
        if (!(StringUtils.isBlank(parameter))) {
            return true;
        } else {
            return false;
        }
    }
}

如何测试和模拟 class ParameterVerify 的方法?

我已经为你破解了一个单元测试。我使用 Mockito to create a mock for ModelAndView. Mocking the ResourceBundle isn't possible as the getString() method is final. So I´m using a dummy implementation 来操纵 return 值。如果你有很多这样的测试,你应该更好地将 ResourceBundle 包装在一个自己的 class 中,它是可模拟的并传递它。但是等等...您不需要模拟或存根 RessourceBundle,因为您可以使用真正的 .properties 文件并在此处传递 null

我写这个测试只是为了让你了解它是如何工作的。

@Test
public void test() {
    String userName = null; // should add message
    ModelAndView modelAndView = Mockito.mock(ModelAndView.class);
    ResourceBundle resourceBundle = new ResourceBundle() {
        @Override
        protected Object handleGetObject(String key) {
            if ("invalidUserName".equals(key)) {
                return "mocked_string";
            }
            return null;
        }

        @Override
        public Enumeration<String> getKeys() {
            return Collections.emptyEnumeration();
        }
    };

    ParameterVerify parameterVerify = new ParameterVerify();
    parameterVerify.verifyParameters(userName, modelAndView, resourceBundle);
    Mockito.verify(modelAndView, Mockito.times(1)).addObject(Mockito.eq("invalidUserName"), Mockito.eq("mocked_string"));
}

最好使用真实的 MessagesBundle_en.properties 文件作为测试资源:

@Test
public void test() {
    String userName = null; // should add message
    ModelAndView modelAndView = Mockito.mock(ModelAndView.class);
    ResourceBundle resourceBundle = null;

    ParameterVerify parameterVerify = new ParameterVerify();
    parameterVerify.verifyParameters(userName, modelAndView, resourceBundle);
    Mockito.verify(modelAndView, Mockito.times(1)).addObject(Mockito.eq("invalidUserName"), Mockito.eq("UserName cannot be null or empty or blank string"));
}