【问题标题】:Testing controllers using Spring, JUNIT, MockMvc and Hamcrest使用 Spring、JUNIT、MockMvc 和 Hamcrest 测试控制器
【发布时间】:2015-07-13 18:44:22
【问题描述】:

我正在尝试测试我的一个控制器,它在 get 方法上返回一个对象列表以填充我页面上的下拉列表。

我正在尝试使用 MockMvc 和 Hamcrest 编写一个 JUnit 测试来进行测试。

我想比较对象列表并测试它是否失败。

我在我的 Test.java 中创建了一个静态对象列表,并且我从 model.attribute 方法中获取了一个对象列表。

测试:如果两个对象列表相等并且不包含任何其他对象。

我的对象称为 Option,它有 3 个属性。键、值和选定。我必须检查列表中是否存在所有键。

我无法创建一个匹配器来做同样的事情。我正在尝试创建一个匹配器来比较我的列表。

到目前为止,我已经完成了以下工作:

@Before
public void setup() throws Exception {
    // This would build a MockMvc with only the following controller
    this.mockMvc = MockMvcBuilders.standaloneSetup(openAccountController)
            .build();
}

@Test
public void testOpenAccount() {
    try {
        setAllLegislations();
        this.mockMvc
                .perform(get("/open_account.htm"))
                // This method is used to print out the actual httprequest
                // and httpresponse on the console.
                .andDo(print())
                // Checking if status is 200
                .andExpect(status().isOk())
                .andExpect(
                        model().attributeExists("appFormAccountPlans",
                                "appFormLiraLegislations",
                                "appFormLrspLegislations",
                                "appFormRlspLegislations"))
                .andExpect(
                        model().attribute("appFormAccountPlans", hasSize(5)))
                .andExpect(
                        model().attribute("appFormLiraLegislations",
                                hasSize(8)))
                .andExpect(
                        model().attribute("appFormLrspLegislations",
                                hasSize(2)))
                .andExpect(
                        model().attribute("appFormRlspLegislations",
                                hasSize(1)))
                .andExpect(
                        model().attribute(
                                "appFormLiraLegislations",
                                hasKeyFeatureMatcher(getLiraLegislations(allLegislations))));


private Matcher<List<Option>> hasKeyFeatureMatcher(
        final List<Option> expectedOptions) {
    return new FeatureMatcher<List<Option>, List<Option>>(
            equalTo(expectedOptions), "Options are", "was") {

        @Override
        protected List<Option> featureValueOf(List<Option> actualOptions) {
            boolean flag = false;
            if (actualOptions.size() == expectedOptions.size()) {
                for (Option expectedOption : expectedOptions) {
                    for (Option actualOption : actualOptions) {
                        if (expectedOption.getKey().equals(
                                actualOption.getKey())) {
                            flag = true;
                        } else {
                            flag = false;
                            break;
                        }
                    }
                }
            }
            if (flag)
                return actualOptions;
            else
                return null;
        }
    };
}

private List<Option> getLiraLegislations(List<Option> legislation) {

    List<Option> liraLegislations = new ArrayList<Option>();
    Iterator<Option> iterator = legislation.iterator();
    while (iterator.hasNext()) {
        Option option = iterator.next();
        if (LIRA_LEGISLATIONS.contains(option.getKey())) {
            liraLegislations.add(option);
        }
    }
    return liraLegislations;
}

private List<Option> allLegislations;

public List<Option> getAllLegislations() {
    return allLegislations;
}

public void setAllLegislations() {
    allLegislations = new ArrayList<Option>();
    for (String key : ALL_LEGISLATIONS) {
        Option option = new Option();
        option.setKey(key);
        allLegislations.add(option);
    }
}

private static final Set<String> ALL_LEGISLATIONS = new HashSet<String>(
        Arrays.asList(AccountLegislationEnum.AB.toString(),
                AccountLegislationEnum.MB.toString(),
                AccountLegislationEnum.NB.toString(),
                AccountLegislationEnum.NL.toString(),
                AccountLegislationEnum.NS.toString(),
                AccountLegislationEnum.ON.toString(),
                AccountLegislationEnum.QC.toString(),
                AccountLegislationEnum.SK.toString(),
                AccountLegislationEnum.BC.toString(),
                AccountLegislationEnum.FE.toString(),
                AccountLegislationEnum.NT.toString(),
                AccountLegislationEnum.PE.toString(),
                AccountLegislationEnum.YT.toString(),
                AccountLegislationEnum.NU.toString(),
                AccountLegislationEnum.UNKNOWN.toString()));

这就是我获取模型属性的方式:

 Attribute = appFormLiraLegislations
           value = [com.abc.arch.core.gui.eform.gui.Option@199d1739, com.abc.arch.core.gui.eform.gui.Option@185fac52, com.abc.arch.core.gui.eform.gui.Option@312a47fe, com.abc.arch.core.gui.eform.gui.Option@4edc8de9, com.abc.arch.core.gui.eform.gui.Option@71e8e471, com.abc.arch.core.gui.eform.gui.Option@70edf123, com.abc.arch.core.gui.eform.gui.Option@15726ac1, com.abc.arch.core.gui.eform.gui.Option@abeafe7]

提前致谢。

【问题讨论】:

    标签: java spring junit hamcrest mockmvc


    【解决方案1】:

    当您使用key 属性正确实现Option 对象hashCode()equals() 方法时,您的生活绝对会更轻松;那么你可以简单地写:

    model().attribute("appFormLiraLegislations",getLiraLegislations(allLegislations)))
    

    并依靠list1.equals(list2) 方法为您完成工作。

    选项hashCodeequals实现:

    public class Option {
    
        private String key;
        private String label;
    
        ...
    
        @Override
        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result + ((key == null) ? 0 : key.hashCode());
            return result;
        }
    
        @Override
        public boolean equals(Object obj) {
            if (this == obj)
                return true;
            if (obj == null)
                return false;
            if (getClass() != obj.getClass())
                return false;
            Option other = (Option) obj;
            if (key == null) {
                if (other.key != null)
                    return false;
            } else if (!key.equals(other.key))
                return false;
            return true;
        }
    
    }
    

    上面的方法是由我的 IDE 生成的。我也不确切知道您的 Option 类的结构是什么,所以我在 key 属性之外添加了 label 属性。

    【讨论】:

    • 你能解释一下怎么回事吗?很抱歉,我在这个问题上苦苦挣扎。
    • 谢谢@Pavla,我从没想过比较这种方式!作为一个魅力工作!
    • 有没有办法不使用上述方法来完成这个?这会改变我的生产代码,我试图避免这种情况!请给我建议!
    【解决方案2】:

    我创建了一个自定义 Hamcrest 匹配器,通过检查大小和键来比较选项列表。

    private Matcher<List<Option>> hasOptionsFeatureMatcher(
            final List<Option> expectedOptions) {
        return new FeatureMatcher<List<Option>, List<Option>>(
                equalTo(expectedOptions), "Options are", "Options were") {
    
            @Override
            protected List<Option> featureValueOf(List<Option> actualOptions) {
                boolean flag = false;
                if (expectedOptions.size() == actualOptions.size()) {
                    for (Option expected : expectedOptions) {
                        for (Option actual : actualOptions) {
                            if (expected.getKey().equals(actual.getKey())) {
                                flag = true;
                                break;
                            } else {
                                flag = false;
                            }
                        }
                    }
                } else
                    flag = false;
                if (flag)
                    return expectedOptions;
                else
                    return null;
            }
    
        };
    

    实现如下:

    private static final ImmutableBiMap<String, String> LIRA = new ImmutableBiMap.Builder<String, String>()
            .put(AccountLegislationEnum.AB.toString(), "ALBERTA")
            .put(AccountLegislationEnum.MB.toString(), "MANITTOBA")
            .put(AccountLegislationEnum.NB.toString(), "NEW BRUNSWICK")
            .put(AccountLegislationEnum.NL.toString(), "NEWFOUNDLAND")
            .put(AccountLegislationEnum.NS.toString(), "NOVA SCOTIA")
            .put(AccountLegislationEnum.ON.toString(), "ONTARIO")
            .put(AccountLegislationEnum.QC.toString(), "QUEBEC")
            .put(AccountLegislationEnum.SK.toString(), "SASKATCHEWAN")
            .put(AccountLegislationEnum.UNKNOWN.toString(), "UNKNOWN").build();
    
    private List<Option> prepareOptions(ImmutableBiMap<String, String> map) {
        List<Option> legislations = new ArrayList<Option>();
        for (Map.Entry<String, String> entry : map.entrySet()) {
            String key = entry.getKey();
            String value = entry.getValue();
            Option option = new Option();
            option.setKey(key);
            option.setValue(value);
            legislations.add(option);
        }
        return legislations;
    }
    
    
    .andExpect(model().attribute("appFormLiraLegislations",hasOptionsFeatureMatcher(prepareOptions(LIRA))))
    

    【讨论】:

      猜你喜欢
      • 2016-11-30
      • 1970-01-01
      • 2014-05-31
      • 1970-01-01
      • 2018-05-25
      • 1970-01-01
      • 1970-01-01
      • 2021-03-14
      • 1970-01-01
      相关资源
      最近更新 更多