Un mot dérivé du mot anglais «double», qui signifie un substitut pour un interprète ou un guerrier de l'ombre. Généralement appelé mock ou stub.
Dans le test unitaire du système, la cible du test est Il y a peu de cas où cela ne dépend pas d'autres classes ou d'éléments externes. Les tests dépendants sont des tests non seulement sur le sujet, mais également sur la dépendance.
L'avantage est que le test est effectué dans le même état que lorsque le système est en cours d'exécution. Il y a un aspect que la valeur du contenu garanti par les résultats des tests augmente. D'autre part, l'inconvénient est que la portée de l'analyse des causes s'élargit lorsque le test échoue. Si le résultat du traitement de l'objet dépendant ne peut pas être prédit, la précision de la vérification diminuera.
En guise de contre-mesure contre les inconvénients ci-dessus, au lieu des facteurs qui affectent le test Il existe un moyen d'augmenter l'indépendance du test en utilisant un substitut facile à tester. C'est l'utilisation de stubs et de faux (test double) pour y parvenir.
Les deux sont utilisés comme substituts des classes et des modules dont dépend la cible du test. Il n'y a pas de différence en termes de classes et de modules. Par conséquent, il est souvent utilisé comme synonyme, mais dans un sens étroit, il existe les différences suivantes.
** Le but est de faire en sorte que l'objet dépendant se comporte de manière prévisible **.
De plus, il est utilisé comme substitut aux objets suivants.
--Comportement imprévisible
** Le but est de vérifier si l'objet dépendant a été appelé lors de l'exécution **.
Traitement difficile à obtenir la valeur souhaitée, comme les nombres aléatoires et les dates système, L'extraction en tant que méthode et classe et la commutation avec un stub facilitent le test. Il existe différentes façons d'implémenter les stubs, mais les détails sont "[Méthode de refactorisation dans JUnit](https://qiita.com/maple_syrup/items/c370f3f850972aafd101#junit%E3%81%AB%E3%81%8A%E3" % 81% 91% E3% 82% 8B% E3% 83% AA% E3% 83% 95% E3% 82% A1% E3% 82% AF% E3% 82% BF% E3% 83% AA% E3% 83 % B3% E3% 82% B0% E3% 81% AE% E6% 89% 8B% E6% B3% 95) ".
Dans l'exemple suivant, le processus d'acquisition de nombres aléatoires est coupé en tant que méthode. Vous avez créé et remplacé une méthode stub dans votre code de test.
Code de production
public class GetRandomElementFromList {
public <T> T choice(List<T> elements) {
if (elements.size() == 0) {
return null;
}
int idx = nextInt() % elements.size();
return elements.get(idx);
}
int nextInt() {
return new Random().nextInt();
}
}
Code de test
public class GetRandomElementFromListTest {
private List<String> elements = new ArrayList<>();
@Before
public void setUp() {
elements.add("A");
elements.add("B");
}
@Test
renvoie A avec le choix public void() {
GetRandomElementFromList sut = new GetRandomElementFromList() {
@Override
int nextInt() {
return 0;
}
};
assertThat(sut.choice(elements), is("A"));
}
@Test
Renvoie B avec le choix public void() {
GetRandomElementFromList sut = new GetRandomElementFromList() {
@Override
int nextInt() {
return 1;
}
};
assertThat(sut.choice(elements), is("B"));
}
}
Il existe de nombreux cas dans lesquels il est difficile de déclencher une exception, telle qu'une erreur de connexion à la base de données. Même dans un tel cas, une méthode qui lève une exception En le coupant en petits morceaux, il est possible de passer par talon.
Le test unitaire de base vérifie la valeur d'entrée et la valeur de sortie comme la méthode assertThat. Par conséquent, il est facile de tester un objet dont la cible de test renvoie une valeur de retour et ne conserve pas son état. D'autre part, le cas de test lorsque l'état de la méthode sans valeur de retour ou l'objet cible change La vérification devient difficile. La vérification devient encore plus difficile lorsque l'état des objets dépendants change.
Un exemple typique d'effets secondaires sur les objets dépendants est Il y a vérification du contenu écrit sur la sortie standard et l'enregistreur. (Parce que l'état des objets dépendants (sortie standard, etc.) change en fonction de l'exécution de la cible de test) Dans ce cas, écrivez un enregistreur ou un objet qui effectue une sortie standard. Il remplace par un objet appelé espion et surveille le traitement caché. L'espion enveloppe et implémente l'objet d'origine.
Voici un exemple d'implémentation de code de test pour vérifier la méthode qui génère les journaux.
Code de production
public class OutputLog {
Logger logger = Logger.getLogger(OutputLog.class.getName());
public void outputLog() {
logger.info("doSomething");
}
}
Code de test(Classe d'espionnage)
public class SpyLogger extends Logger{
final Logger base;
//Variable de classe pour référencer le journal du côté test séparément de la sortie du journal
final StringBuffer log = new StringBuffer();
public SpyLogger(Logger base) {
super(base.getName(), base.getResourceBundleName());
this.base = base;
}
//Méthode pour être un stub
@Override
public void info(String message) {
base.info(message);
//Traitement supplémentaire → Sortie vers le StringBuffer que l'espion a indépendamment
log.append(message);
}
}
Code de test(cas de test)
public class SpyExampleTest {
@Test
public void test() {
OutputLog sut = new OutputLog();
SpyLogger spyLogger = new SpyLogger(sut.logger);
//Remplacez l'enregistreur testé par un enregistreur espion
sut.logger = spyLogger;
sut.outputLog();
assertThat(spyLogger.log.toString(), is("doSomething"));
}
}
Cet article a été rédigé en référence aux informations suivantes.
Recommended Posts