【问题标题】:Spring MVC Test with Hamcrest: How compare a XML's node directly against a Java object使用 Hamcrest 进行 Spring MVC 测试:如何将 XML 的节点直接与 Java 对象进行比较
【发布时间】:2016-09-13 18:28:26
【问题描述】:

我正在与:

  • Spring MVC 测试
  • 哈姆克雷斯特

对于集合中的一个项目,例如:

<collection>
    <item xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="persona">
        <id>087</id>
        <nombre>Leonardo</nombre>
        <apellido>Jordan</apellido>
        <fecha>1981-07-05</fecha>
    </item>
    ....

以下作品:

.andExpect(xpath("collection/item[1]").exists())
.andExpect(xpath("collection/item[1]/*").nodeCount(is(4)))
.andExpect(xpath("collection/item[1]/id").exists())
.andExpect(xpath("collection/item[1]/id").string(is("087")))
.andExpect(xpath("collection/item[1]/id").string(is(personasArray[0].getId())))
.andExpect(xpath("collection/item[1]/nombre").exists())
.andExpect(xpath("collection/item[1]/nombre").string(is("Leonardo")))
.andExpect(xpath("collection/item[1]/nombre").string(is(personasArray[0].getNombre())))
.andExpect(xpath("collection/item[1]/apellido").exists())
.andExpect(xpath("collection/item[1]/apellido").string(is("Jordan")))
.andExpect(xpath("collection/item[1]/apellido").string(is(personasArray[0].getApellido())))

我想知道是否可以直接比较对象而不是每个字段,考虑一个具有 15 到 45 个字段的实体。

我需要这样的东西:

.andExpect(xpath("collection/item[1]/*").how(is(personasArray[0])))

参见how 部分,它代表了正确的使用方法。 对path 的字符串内容同样考虑。

【问题讨论】:

    标签: xml xpath spring-test-mvc


    【解决方案1】:

    可以做这样的断言。但是您需要为此编写自定义ResultMatcher。我认为将 XML(节点)转换为 Java 对象只是为了在单元测试中进行简单比较并不是一个好主意。 如果没有正确实施,您可能会遇到 XML 命名空间解析或 Java hashCode equals 合约的问题。

    相反,您应该使用可让您专注于单元测试而不是技术或编程语言细节的库。

    我建议您在测试中使用XMLUnitXMLUnit 是一个用于 XML 比较的 Java 库。

    下面的示例描述了将 XML 文档与 XMLUnit 和自定义 ResultMatcher 进行比较是多么容易。

    import org.hamcrest.Matcher;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
    import org.springframework.test.context.junit4.SpringRunner;
    import org.springframework.test.web.servlet.MockMvc;
    import org.springframework.test.web.servlet.ResultMatcher;
    import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    import org.xmlunit.builder.Input;
    
    import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
    import static org.xmlunit.matchers.CompareMatcher.isSimilarTo;
    
    @RunWith(SpringRunner.class)
    @WebMvcTest(XmlUnitDemoTests.XmlUnitDemo.class)
    public class XmlUnitDemoTests {
    
        static final String XML_CONTENT = "<node1><node2 id=\"1\">text</node2></node1>";
    
        @Autowired
        MockMvc mockMvc;
    
        @Test
        public void xmlUnit() throws Exception {
            mockMvc.perform(get("/xml"))
                .andExpect(xml(XML_CONTENT));
        }
    
        static ResultMatcher xml(String bodyValue) {
            return MockMvcResultMatchers.content().source(equalXml(bodyValue));
        }
    
        static Matcher equalXml(String value) {
            return isSimilarTo(Input.fromString(value).build());
        }
    
        @SpringBootApplication
        @RestController
        static class XmlUnitDemo {
    
            @RequestMapping(value = "xml", produces = "text/xml")
            String xml() {
                return XML_CONTENT;
            }
        }
    
    }
    

    当然,您可以从类路径加载大型 XML 文件,或者在进行比较之前使用 XPatch 选择一个节点。请查看XMLUnit 文档以了解更多信息。

    【讨论】:

    • 感谢您的帖子,我会检查您的宝贵建议。现在关于I don't think it is a good idea to convert XML (nodes) to Java objects just to do a simple comparison in a unit test 我会同意。我理解您的观点,当然是有效的,但我必须假设远程客户端具有 OXM 技术。我和杰克逊一起为XMLJSON 工作。
    • 您可以更好地了解您的项目设置,并且您是唯一能够做出正确决定的人。我只是想和你分享我的观点和经验。
    • 我并不是说你的意见是错误的。我同意,但我的意思是做quick @Test 编码。想象一下,如果您向域类添加或重构。我会测试你的建议。这是有价值的。一切正常。再次感谢您的帖子。
    • 我只想礼貌地说,您知道项目的位和字节,因此只有您可以决定选项 a 或 b 是否更适用。这里没有双关语。继续滚动:-)
    猜你喜欢
    • 1970-01-01
    • 2012-08-21
    • 1970-01-01
    • 1970-01-01
    • 2016-04-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-21
    • 2022-09-30
    相关资源
    最近更新 更多