具有相同输出的ArrayList上的AssertionError

时间:2018-07-06 09:05:29

标签: spring unit-testing spring-data-jpa

我知道这个话题已经问了很多遍了,我在寻找所有可能的解决方案,但不幸的是,没有任何一个解决我的问题的。

这是我的测试用例:

@Test
    public void whenFindAllBy_thenReturnListofViewPlanDetailDto() {
        java.sql.Date startDate = new java.sql.Date(new Date().getTime());
        java.sql.Date endDate = new java.sql.Date(new Date().getTime());
        Plan planA = new Plan();
        planA.setName("Plan A - 2018");
        entityManager.persist(planA);
        entityManager.flush();
        Module moduleA = new Module();
        moduleA.setName("CSS");
        moduleA.setDescription("CSS is a cornerstone technology of the World Wide Web, alongside HTML and JavaScript.");
        entityManager.persist(moduleA);

        Module moduleB = new Module();
        moduleB.setName("HTML");
        moduleB.setDescription("Hypertext Markup Language is the standard markup language for creating web pages and web applications.");
        entityManager.persist(moduleB);

        PlanDetail planDetailA = new PlanDetail();
        planDetailA.setInstructor("Mozilla Firefox Foundation");
        planDetailA.setStartDate(startDate);
        planDetailA.setEndDate(endDate);
        planDetailA.setModule(moduleA);
        planDetailA.setPlan(planA);
        entityManager.persist(planDetailA);


        PlanDetail planDetailB = new PlanDetail();
        planDetailB.setInstructor("W3 Schools");
        planDetailB.setStartDate(startDate);
        planDetailB.setEndDate(endDate);
        planDetailB.setModule(moduleB);
        planDetailB.setPlan(planA);
        entityManager.persist(planDetailB);

        entityManager.flush();

        List<ViewPlanDetailDto> plandetails = new ArrayList<>();
        plandetails.add(new ViewPlanDetailDto(planDetailA.getId(), planDetailA.getModule().getName(), planDetailA.getModule().getDescription(), planDetailA.getInstructor(), planDetailA.getStartDate(), planDetailA.getEndDate()));
        plandetails.add(new ViewPlanDetailDto(planDetailB.getId(), planDetailB.getModule().getName(), planDetailB.getModule().getDescription(), planDetailB.getInstructor(), planDetailB.getStartDate(), planDetailB.getEndDate()));

        assertEquals(planRepository.findAllBy(planA.getId()), plandetails);

    }

Stacktrace:

java.lang.AssertionError: expected: java.util.ArrayList<[ViewPlanDetailDto(detailId=1, name=CSS, description=CSS is a cornerstone technology of the World Wide Web, alongside HTML and JavaScript., instructor=Mozilla Firefox Foundation, startDate=2018-07-06, endDate=2018-07-06), ViewPlanDetailDto(detailId=2, name=HTML, description=Hypertext Markup Language is the standard markup language for creating web pages and web applications., instructor=W3 Schools, startDate=2018-07-06, endDate=2018-07-06)]> but was: java.util.ArrayList<[ViewPlanDetailDto(detailId=1, name=CSS, description=CSS is a cornerstone technology of the World Wide Web, alongside HTML and JavaScript., instructor=Mozilla Firefox Foundation, startDate=2018-07-06, endDate=2018-07-06), ViewPlanDetailDto(detailId=2, name=HTML, description=Hypertext Markup Language is the standard markup language for creating web pages and web applications., instructor=W3 Schools, startDate=2018-07-06, endDate=2018-07-06)]>

我尝试的方法: 覆盖等于PlanDetail,ViewPlanDetailDto,Plan 但一切都失败了。

等于和哈希码替代:

@Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (!(obj instanceof ViewPlanDetailDto))
            return false;
        ViewPlanDetailDto other = (ViewPlanDetailDto) obj;
        if (description == null) {
            if (other.description != null)
                return false;
        } else if (!description.equals(other.description))
            return false;
        if (detailId == null) {
            if (other.detailId != null)
                return false;
        } else if (!detailId.equals(other.detailId))
            return false;
        if (endDate == null) {
            if (other.endDate != null)
                return false;
        } else if (!endDate.equals(other.endDate))
            return false;
        if (instructor == null) {
            if (other.instructor != null)
                return false;
        } else if (!instructor.equals(other.instructor))
            return false;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        if (startDate == null) {
            if (other.startDate != null)
                return false;
        } else if (!startDate.equals(other.startDate))
            return false;
        return true;
    }


    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((description == null) ? 0 : description.hashCode());
        result = prime * result + ((detailId == null) ? 0 : detailId.hashCode());
        result = prime * result + ((endDate == null) ? 0 : endDate.hashCode());
        result = prime * result + ((instructor == null) ? 0 : instructor.hashCode());
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        result = prime * result + ((startDate == null) ? 0 : startDate.hashCode());
        return result;
    }

当我尝试断言它时,即使输出相同,它也总是失败。

基于IntelliJ的比较失败,它在预期部分的跟踪空间上突出显示了我所不知道的结尾空间。

>

Difference

1 个答案:

答案 0 :(得分:0)

您可能不正确地覆盖了equals()
要理解和纠正您的问题,您应该从基础开始:对equals()方法进行单元测试(并考虑重写hashCode()以与equals()合约保持一致)。

无论如何,通过指定类的所有实例字段在单元测试中进行某些声明来覆盖equals()通常是可以避免的,并且如果它给{{1} }。
equals()的语义在equals()中定义:

  

指示其他某个对象是否“等于”该对象。

您应该坚持下去。
通常,我使用单元测试匹配器库(例如Harmcrest或AssertJ)以非介入方式在对象字段上执行断言,同时又简单明了。

使用AssertJ,您的断言可能类似于:

Object.equals()