web-dev-qa-db-fra.com

Affirmer que Optional a une certaine valeur

J'ai une méthode Java qui retourne un Facultatif ..__ Je voudrais écrire un test unitaire facile à lire, qui affirme que

  1. facultatif renvoyé a une valeur (c’est-à-dire que l’option facultative n’est pas vide) et que

  2. la valeur renvoyée est égale à une valeur attendue.

Disons que ma méthode testée est

Optional<String> testedMethod(){
  return Optional.of("actual value");
}
16
Matthias Braun

Vous pouvez également utiliser AssertJ pour des assertions fluides

@Test
public void testThatOptionalIsNotEmpty() {
    assertThat(testedMethod()).isNotEmpty();
}

@Test
public void testThatOptionalHasValue() {
    assertThat(testedMethod()).hasValue("hello");
}
23
Spotted

TL; DR la meilleure approche globale a été suggérée par Ole V. V .:

assertEquals(Optional.of("expected"), opt);

D'autres alternatives sont discutées ci-dessous.

Il existe plusieurs façons de procéder, en fonction de votre goût pour la clarté des résultats de test par rapport à la concision de la rédaction du test. Pour cette réponse, je vais m'en tenir à "stocker" Java 8 et JUnit 4 sans dépendances supplémentaires.

Une façon, comme suggéré dans un commentaire de Ole V.V. , est simplement d'écrire

assertEquals("expected", opt.get());

Cela fonctionne la plupart du temps, mais si Facultatif est vide, alors get() lancera NoSuchElementException. À son tour, JUnit signale une erreur au lieu d’un échec, ce qui pourrait ne pas être ce que vous souhaitiez. Il n’est pas clair non plus ce qui se passe à moins que vous ne sachiez déjà que get() jette NSEE dans ce cas.

Une alternative est

assertTrue(opt.isPresent() && "expected".equals(opt.get()));

Cela fonctionne aussi généralement, mais il ne rapporte pas la valeur réelle s'il y a une incompatibilité, ce qui pourrait rendre le débogage incommode.

Une autre alternative est

assertEquals("expected", opt.orElseThrow(AssertionFailedError::new));

Cela donne les échecs appropriés et indique la valeur réelle en cas de non concordance, mais la raison pour laquelle AssertionFailedError est jeté n'est pas explicite. Vous devrez peut-être regarder longuement jusqu'à ce que vous réalisiez que AFE est lancé lorsque l'option est vide.

Encore une autre alternative est

assertEquals("expected", opt.orElseThrow(() -> new AssertionFailedError("empty")));

mais cela commence à devenir verbeux.

Vous pouvez scinder cela en deux affirmations,

assertTrue(opt.isPresent());
assertEquals("expected", opt.get());

mais vous aviez déjà fait objection à cette suggestion à cause de la verbosité. À mon avis, ce n’est pas vraiment très verbeux, mais il ya une surcharge cognitive car il y a deux affirmations distinctes, et la seconde ne doit être vérifiée que si la première réussit. Ce n’est pas faux mais c’est un peu subtil.

Enfin, si vous souhaitez créer un peu de votre propre infrastructure, vous pouvez créer une sous-classe de AssertionFailedError portant le nom approprié et l'utiliser comme suit:

assertEquals("expected", opt.orElseThrow(UnexpectedEmptyOptional::new));

Enfin, dans un autre commentaire, Ole V. V. a suggéré

assertEquals(Optional.of("correct"), opt);

Cela fonctionne assez bien, et en fait cela pourrait être le meilleur de tous.

17
Stuart Marks

L'approche ci-dessous utilise le fait que vous pouvez spécifier un retour par défaut pour un optionnel. Donc, votre méthode de test pourrait être quelque chose comme ceci:

@test
public void testThatOptionalHasValue() {
    String expectedValue = "actual value";
    String actualValue = Optional.ofNullable(testedMethod()).orElse("not " + expectedValue);
    assertEquals("The values are not the same", expectedValue, actualValue);
}

Cela garantit que si votre méthode renvoie null, le résultat ne peut pas être identique à la valeur attendue.

1
Ben Green

J'utilise Hamcrest Facultatif pour cela:

import static com.github.npathai.hamcrestopt.OptionalMatchers.hasValue;
import org.junit.Test;

public class MyUnitTests {

  @Test
  public void testThatOptionalHasValue(){
    String expectedValue = "actual value";
    assertThat(testedMethod(), hasValue(expectedValue));
  }
}

Vous pouvez ajouter Hamcrest Optional à vos dépendances en l'incluant dans votre build.gradle:

dependencies {
  testCompile 'junit:junit:4.12'
  testCompile 'com.github.npathai:hamcrest-optional:1.0'
}
1
Matthias Braun

Pourquoi n’utilisez-vous pas isPresent() et get()?

0
mzq