简体   繁体   中英

JUnit fails when run two tests with same variable name execute

I have written the following tests for my classes:

import org.junit.After;
import org.joda.time.LocalDateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import org.junit.Test;

import static org.assertj.core.api.Assertions.assertThat;

public class ScheduleUnitTest {
    private DateTimeFormatter formatter = DateTimeFormat.forPattern("dd-MM-yyyy HH:mm");

    @Test
    public void test1() {
        // Available 8:00 - 18:00
        // Break 12:00 - 12:30
        Schedule schedule = new Schedule();
        ScheduleElement element;

        element = new ScheduleElement();
        element.setType(EventType.AVAILABLE);
        element.setBegin(getDate("20-08-2014 08:00"));
        element.setEnd(getDate("20-08-2014 18:00"));
        schedule.addElement(element);

        element = new ScheduleElement();
        element.setType(EventType.UNAVAILABLE);
        element.setBegin(getDate("20-08-2014 12:00"));
        element.setEnd(getDate("20-08-2014 12:30"));
        schedule.addElement(element);

        schedule.make();

        assertThat(schedule.isAvailable(getDate("20-08-2014 12:10"), getDate("20-08-2014 12:20"))).isFalse();
    }

    @Test
    public void test2() {
        // Available 8:00 - 18:00
        // Break 12:00 - 12:30
        Schedule schedule = new Schedule();
        ScheduleElement element;

        element = new ScheduleElement();
        element.setType(EventType.AVAILABLE);
        element.setBegin(getDate("20-08-2014 08:00"));
        element.setEnd(getDate("20-08-2014 18:00"));
        schedule.addElement(element);

        element = new ScheduleElement();
        element.setType(EventType.UNAVAILABLE);
        element.setBegin(getDate("20-08-2014 12:00"));
        element.setEnd(getDate("20-08-2014 13:30"));
        schedule.addElement(element);

        element = new ScheduleElement();
        element.setType(EventType.AVAILABLE);
        element.setBegin(getDate("20-08-2014 12:30"));
        element.setEnd(getDate("20-08-2014 13:30"));
        schedule.addElement(element);

        schedule.make();

        assertThat(schedule.isAvailable(getDate("20-08-2014 12:10"), getDate("20-08-2014 12:20"))).isFalse();
    }

    private LocalDateTime getDate(String date) {
        return LocalDateTime.parse(date, formatter);
    }

}

When I run both tests, then one of them always fails. It says:

test2(org.example.ScheduleUnitTest)  Time elapsed: 0.011 sec  <<< FAILURE!
org.junit.ComparisonFailure: expected:<[fals]e> but was:<[tru]e>

But when I run both separately, then both tests pass. The solution is to change name of Schedule schedule = new Schedule(); for schedule1 and schedule2 . Then, once again, both pass.

Why does it work like that?

EDIT Here is source code for the Schedule class:

import org.joda.time.LocalDateTime;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class Schedule {

    private List<ScheduleElement> elements = new ArrayList<ScheduleElement>();

    public void make() {
        // sorted ASC
        Collections.sort(elements, new Comparator<ScheduleElement>() {
            public int compare(ScheduleElement o1, ScheduleElement o2) {
                return o2.getCreated().compareTo(o1.getCreated());
            }
        });
    }

    public boolean isAvailable(LocalDateTime begin, LocalDateTime end) {
        for(ScheduleElement scheduleElement : elements) {
            if(scheduleElement.isOccurring(begin, end)) {
                if(scheduleElement.getType() == EventType.AVAILABLE) {
                    if(!begin.isBefore(scheduleElement.getBegin()) && !end.isAfter(scheduleElement.getEnd())) {
                        return true;
                    }
                }

                return false;
            }
        }

        return false;
    }

    public boolean isOccurring(LocalDateTime date, EventType type) {
        for(ScheduleElement scheduleElement : elements) {
            if(scheduleElement.isOccurring(date, type)) {
                return true;
            }
        }

        return false;
    }

    public void dates(LocalDateTime begin, LocalDateTime end) {

    }

    public void dates(LocalDateTime begin, LocalDateTime end, EventType eventType) {

    }

    public void addElement(ScheduleElement element) {
        elements.add(element);
    }

    public List<ScheduleElement> getElements() {
        return elements;
    }

    public void setElements(List<ScheduleElement> elements) {
        this.elements = elements;
    }
}

SOLVED

The problem was somewhere else: schedule.make() has Collections.sort . It sorted array in wrong way. ScheduleElement has property

private LocalDateTime created = LocalDateTime.now();

And often it doesn't mean if I put element = new ScheduleElement() ; one by one, then I mean that order created is different, but not. I need to set up property manually, and then it works.

I'm sorry for that!

I don't think that the code for Schedule is the problem, because you are instantiating it locally within the test, and there is no static data to share between threads. I believe that the problem may be your date parsing in the test class, itself, which gets executed in parallel when the tests run together in parallel. Try the following change to getDate() ::

private LocalDateTime getDate(String date) {
    synchronized (LocalDateTime.class) {
        return LocalDateTime.parse(date, formatter);
    }
}

This will ensure that no two calls to parse() occur in parallel within your JVM.

make the following changes to the unit test, thins might fix your problem.

  • Add a @Before method( setup ) and initialize schedule inside that.

So the test becomes something like this..

private Schedule schedule;

@Before
public void setUp() throws Exception {
    schedule = new Schedule();
}

@Test
public void test1() {
   // setting values go here.

     schedule.make();
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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