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;
}