Home > Software engineering >  Test that at least one element of a list contains a specific element using assertj
Test that at least one element of a list contains a specific element using assertj

Time:09-29

Suppose i have players which form a team which participates at a tournament. I want to test, that the tournament has at least one team with name T1 with a player named Paul.

package org.example;

import java.util.List;

public class Tournament {
    List<Team> teams;
    public Tournament(){
    }

    public void create(){
        
    }

    public List<Team> getTeams() {
        return this.teams;
    }
}

package org.example;

import java.util.List;

public class Team {
    List<Player> players;
    private String name;

    public Team(String name, List<Player> players){
        this.players = players;
        this.name = name;
    }

    public List<Player> getPlayers(){
        return this.players;
    }

    public String getName() {
        return this.name;
    }
}

package org.example;

public class Player {
    String firstName;

    public Player(String firstName){
        this.firstName = firstName;
    }

    public String getFirstName(){
        return this.firstName;
    }
}

The test should look like this:

Tournament tournament = new Tournament();
tournament.create();
assertThat(tournament)
  .hasAtLeastOneTeam()
  .withName("T1")
  .withAPlayer()
  .named("Paul")

How is it possible to do this with AssertJ?

CodePudding user response:

As mentioned in Annamalai's answer, custom assertions would be the way to achieve the API in your example.

However, if relying on the existing AssertJ API is an option, here is a possible solution with anySatisfy:

assertThat(tournament.getTeams()).anySatisfy(team -> {
  assertThat(team.getName()).isEqualTo("T1");
  assertThat(team.getPlayers()).extracting(Player::getFirstName).contains("Paul");
});

CodePudding user response:

The below classes might solve your problem.

TournamentAssert

public class TournamentAssert extends AbstractAssert<TournamentAssert, Tournament> {
    public TournamentAssert(Tournament actual) {
        super(actual, TournamentAssert.class);
    }
    public static TournamentAssert assertThat(Tournament actual) {
        return new TournamentAssert(actual);
    }
    public TournamentAssert hasAtLeastOneTeam() {
        isNotNull();
        if (actual.getTeams().size() > 0) {
            failWithMessage("Expected at least one team But actual size is: <%s>", actual.getTeams().size());
        }
        return this;
    }
    public TeamAssert withName(String name) {
        isNotNull();
        for(Team team: actual.getTeams()) {
            if(name.equals(team.getName())) {
                return TeamAssert.assertThat(team);
            }
        }
        return TeamAssert.assertThat(null);
    }
}

TeamAssert

public class TeamAssert extends AbstractAssert<TeamAssert, Team> {
    public TeamAssert(Team actual) {
        super(actual, TeamAssert.class);
    }
    public static TeamAssert assertThat(Team actual) {
        return new TeamAssert(actual);
    }
    public TeamAssert withAPlayer() {
        isNotNull();
        if (actual.getPlayers().size() == 1) {
            for(Player player: actual.getPlayers()) {
                PlayerAssert.assertThat(player);
            }
        }
        return this;
    }
}

PlayerAssert

public class PlayerAssert extends AbstractAssert<PlayerAssert, Player> {
    public PlayerAssert(Player actual) {
        super(actual, PlayerAssert.class);
    }
    public static PlayerAssert assertThat(Player actual) {
        return new PlayerAssert(actual);
    }
    public PlayerAssert named(String name) {
        isNotNull();
        if (!name.equals(actual.getFirstName())) {
            failWithMessage("Expected a player name is: <%s> But actual name is <%s>",name,  actual.getFirstName());
        }
        return this;
    }
}

You can also assert with a single function in TournamentAssert if you want:

public TeamAssert withNameAndAPlayerAndNamed(String name, String playerName) {
            isNotNull();
            for(Team team: actual.getTeams()) {
                if(name.equals(team.getName())) {
                    if (team.getPlayers().size() == 1) {
                        for(Player player: team.getPlayers()) {
                            if (!playerName.equals(player.getFirstName())) {
                                failWithMessage("Expected a player name is: <%s> But actual name is <%s>",name,  player.getFirstName());
                            }
                        }
                    }
                }
            }
            return this;
        }
  • Related