简体   繁体   中英

Parameterized tests fail with mvn test

I'm struggeling quite a bit with a simple parameterized java test and couldn't find a proper solution :-S

Maybe you can give a hint where i missed something.

Following scenarios I have been testing running with

  • intellij -> no error, all tests pass
  • mvn clean -Dtest:KnockoutTests test -> no error, all tests pass
  • mvn clean test (locally and on jenkins) -> ArrayIndexOutOfBoundsException

集初始化失败

When I'm copying the exactly generated hashCode method in my class RoundDefinition it works just fine. But I don't want to explicitely override the hashCode method with exactly the generated one... (and this cannot be the solution obviously)

Models

@Entity
@Data
@Table( name = "tbl_rounddefinition" )
@JsonIgnoreProperties( value = { "hibernateLazyInitializer", "handler", }, ignoreUnknown = true )
@ToString( exclude = { "tournament" } )
@EqualsAndHashCode( exclude = { "tournament" } )
public class RoundDefinition implements Serializable {

    @Id
    @GeneratedValue( strategy = IDENTITY )
    @Column( name = "rounddefinition_id" )
    private Long id;

    @ManyToOne( fetch = FetchType.LAZY )
    @JoinColumn( name = "rounddefinition_linktournamentid" )
    @JsonIdentityInfo( generator = ObjectIdGenerators.PropertyGenerator.class, property = "id" )
    @JsonIdentityReference( alwaysAsId = true )
    private Tournament tournament;

    @Column( name = "rounddefinition_round" )
    private Integer round;

    @Column( name = "rounddefinition_numberOfRoundresults" )
    private Integer numberOfRoundresults;
}
@Data
@ToString( exclude = { [...] } )
@EqualsAndHashCode( exclude = { [...], "roundDefinitions" } )
@Entity
@Table( name = "tbl_tournament" )
@JsonIgnoreProperties( value = { "hibernateLazyInitializer", "handler" }, ignoreUnknown = true )
public class Tournament implements Serializable {

[...]

    @OneToMany( fetch = FetchType.LAZY, mappedBy = "tournament", cascade = CascadeType.ALL, orphanRemoval = true )
    @JsonSerialize( using = CollectionSerializer.class )
    @JsonDeserialize( using = CollectionDeserializer.class )
    @OrderBy( " round ASC " )
    private Set<RoundDefinition> roundDefinitions = new HashSet<>();

[...]

}

Test

@RunWith( Parameterized.class )
@Slf4j
public class KnockoutTests {

    @InjectMocks
    private Knockout underTest;

    @Mock
    private MatchRepository matchRepository;

    private Integer tournamentSize;
    private Integer expectedMatchSize;
    private Integer expectedMaxRound;
    private List<RoundDefinition> roundDefinitions;

    public KnockoutTests( Integer tournamentSize, Integer expectedMatchSize, Integer expectedMaxRound,
            List<RoundDefinition> roundDefinitions )
    {
        this.tournamentSize = tournamentSize;
        this.expectedMatchSize = expectedMatchSize;
        this.expectedMaxRound = expectedMaxRound;
        this.roundDefinitions = roundDefinitions;
    }

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks( this );
    }

    @Test
    public void testGenerate() {
        Tournament tournament = new Tournament();
        tournament.setTeamsize( 1 );
        System.out.println( "############# " + roundDefinitions.toString() + " #############" );
        tournament.setRoundDefinitions( new HashSet<>( roundDefinitions ) ); // <<-- Here I'm getting this weird ArrayIndexOutOfBoundsExceptions
        [...]
    }

    @Parameterized.Parameters( name = "{index}: Test with tournamentSize={0}, expectedMatchSize: {1}, expectedMaxRound: {2}" )
    public static Collection testData() {
        return Arrays.asList( new Object[][] {
                { 1, 1, 1, new ArrayList<RoundDefinition>() {{
                    add( getRoundDefinition( 1L, 1, 1 ) );
                }} },
                { 2, 1, 1, new ArrayList<RoundDefinition>() {{
                    add( getRoundDefinition( 1L, 1, 1 ) );
                }} },
                { 15, 15, 4, new ArrayList<RoundDefinition>() {{
                    add( getRoundDefinition( 1L, 1, 1 ) );
                    add( getRoundDefinition( 2L, 3, 3 ) );
                    add( getRoundDefinition( 3L, 4, 5 ) );
                }} },
                { 16, 15, 4, new ArrayList<RoundDefinition>() {{
                    add( getRoundDefinition( 1L, 1, 1 ) );
                }} },
                { 17, 31, 5, new ArrayList<RoundDefinition>() {{
                    add( getRoundDefinition( 1L, 1, 1 ) );
                }} },
                { 129, 255, 8, new ArrayList<RoundDefinition>() {{
                    add( getRoundDefinition( 1L, 1, 1 ) );
                }} },
                { 256, 255, 8, new ArrayList<RoundDefinition>() {{
                    add( getRoundDefinition( 1L, 1, 1 ) );
                }} },
                { 257, 511, 9, new ArrayList<RoundDefinition>() {{
                    add( getRoundDefinition( 1L, 1, 1 ) );
                    add( getRoundDefinition( 2L, 3, 3 ) );
                    add( getRoundDefinition( 3L, 4, 5 ) );
                }} }
        } );
    }

    private static RoundDefinition getRoundDefinition( long id, int round, int numberOfRoundresults ) {
        RoundDefinition rd = new RoundDefinition();
        rd.setId( id );
        rd.setRound( round );
        rd.setNumberOfRoundresults( numberOfRoundresults );
        return rd;
    }
[...]
}

Console output

############# [RoundDefinition(id=1, tournament=null, round=1, numberOfRoundresults=1)] #############

############# [RoundDefinition(id=1, tournament=null, round=1, numberOfRoundresults=1), RoundDefinition(id=2, tournament=null, round=3, numberOfRoundresults=3), RoundDefinition(id=3, tournament=null, round=4, numberOfRoundresults=5)] #############
############# [RoundDefinition(id=1, tournament=null, round=1, numberOfRoundresults=1)] #############
############# [RoundDefinition(id=1, tournament=null, round=1, numberOfRoundresults=1)] #############
############# [RoundDefinition(id=1, tournament=null, round=1, numberOfRoundresults=1)] #############
############# [RoundDefinition(id=1, tournament=null, round=1, numberOfRoundresults=1)] #############
############# [RoundDefinition(id=1, tournament=null, round=1, numberOfRoundresults=1), RoundDefinition(id=2, tournament=null, round=3, numberOfRoundresults=3), RoundDefinition(id=3, tournament=null, round=4, numberOfRoundresults=5)] #############
Tests run: 8, Failures: 0, Errors: 8, Skipped: 0, Time elapsed: 0.015 sec <<< FAILURE! - in pkg.service.tournament.handler.generator.KnockoutTests
testGenerate[0: Test with tournamentSize=1, expectedMatchSize: 1, expectedMaxRound: 1](pkg.service.tournament.handler.generator.KnockoutTests)  Time elapsed: 0.008 sec  <<< ERROR!
java.lang.ArrayIndexOutOfBoundsException: 35
    at pkg.model.entities.RoundDefinition.hashCode(RoundDefinition.java:26)
    at java.util.HashMap.hash(HashMap.java:339)
    at java.util.HashMap.put(HashMap.java:612)
    at java.util.HashSet.add(HashSet.java:220)
    at java.util.AbstractCollection.addAll(AbstractCollection.java:344)
    at java.util.HashSet.<init>(HashSet.java:120)
    at pkg.service.tournament.handler.generator.KnockoutTests.testGenerate(KnockoutTests.java:67)

testGenerate[1: Test with tournamentSize=2, expectedMatchSize: 1, expectedMaxRound: 1](pkg.service.tournament.handler.generator.KnockoutTests)  Time elapsed: 0 sec  <<< ERROR!
java.lang.ArrayIndexOutOfBoundsException: 35
    at pkg.model.entities.RoundDefinition.hashCode(RoundDefinition.java:26)
    at java.util.HashMap.hash(HashMap.java:339)
    at java.util.HashMap.put(HashMap.java:612)
    at java.util.HashSet.add(HashSet.java:220)
    at java.util.AbstractCollection.addAll(AbstractCollection.java:344)
    at java.util.HashSet.<init>(HashSet.java:120)
    at pkg.service.tournament.handler.generator.KnockoutTests.testGenerate(KnockoutTests.java:67)

Generated code by lombok

public int hashCode() {
        int PRIME = true;
        int result = 1;
        Object $id = this.getId();
        int result = result * 59 + ($id == null ? 43 : $id.hashCode());
        Object $round = this.getRound();
        result = result * 59 + ($round == null ? 43 : $round.hashCode());
        Object $numberOfRoundresults = this.getNumberOfRoundresults();
        result = result * 59 + ($numberOfRoundresults == null ? 43 : $numberOfRoundresults.hashCode());
        return result;
    }

#2 Edit:

switched to an explicit generation

Set<RoundDefinition> definitions = new HashSet<>(  );
        for (RoundDefinition rd : roundDefinitions) {
            RoundDefinition asd = new RoundDefinition();
            asd.setRound( rd.getRound() );
            asd.setNumberOfRoundresults( rd.getNumberOfRoundresults() );
            definitions.add(asd); // <-- ArrayIndexOutOfBoundsException
        }

#3 Edit:

Out of curiosity i tried to add an element to a different set of class

Set<Tournament> tournamentSet = new HashSet<>();
tournamentSet.add(new Tournament()); <-- ArrayIndexOutOfBoundsException

Also add such initialisation to an other test... same behaviour oO BUT i can add string to a HashSet<String> ... the heck is going on here :-D

#4 Edit:

checked dependencies for change but they seem to be same with source branch. Also reproducable in source branch...

#5 Edit:

Removed the lombok annotation "@Data" from my model "RoundDefinition", wrote getter and setter myself and the tests work again just fine... using lombok v1.18.8

So why is it failing when lombok generates the hashCode and equals function....

Soooo finally I've got to a point with which I can get on...

As I tested several tries, I noticed that my tests somehow worked again.

When I run the tests with profile they failed, when run without a profile they worked. After some digging and refactoring I've got to the pom file of the project...

The plugin "maven-sufefire-plugin" was added 2 times like so

<project>
<profiles>
[...]
<profile>
 <id>unit-test</id>
  <plugins>
   [...]
   <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <configuration>
     <argLine>
      ${argLine} -Dfile.encodeing=utf-8 -Duser.timezone=UTC
     </argLine>
    </configuration>
   </plugin>
[...]
<project>
 <build>
  <plugins>
   [...]
   <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <configuration>
     <argLine>
      -Dfile.encodeing=utf-8 -Duser.timezone=UTC
     </argLine>
    </configuration>
   </plugin>
[...]

but the property ${argLine} was not set in the pom file at all. So I introduced a new property <argLine> and put those parameters in there.... and voilà it worked.... Don't know exactly why there is then an exception thrown in the hashcode method but maybe this helps someone else too :-)

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