[JAVA] Comment tester l'étendue privée avec JUnit

Tester ce qu'est la portée privée

Appeler des champs, des méthodes et des classes internes de portée privée en externe en Java Testons-le avec JUnit.

Tout d'abord, essayons de tester avec JUnit.

error.png

Il y a une erreur de compilation. C'est une spécification. Ne peut pas être exécuté. Puisqu'il est privé, il ne peut pas être appelé de la même manière que public.

Nous utilisons donc Reflection pour appeler quelque chose de portée privée.

Qu'est-ce que la réflexion?

Reflection est une sorte de bibliothèque standard Java. Il s'agit d'informations sur la classe elle-même. Comme exemple concret Avec une chaîne de nom de classe, nom de méthode et nom de champ Générer cette classe, exécuter des méthodes, accéder aux champs Je peux le faire.

Ce qui suit est un site externe, mais il ressemble à ceci, par exemple. http://java.keicode.com/lang/reflection.php

"Si c'est si pratique, utilisez-le de manière positive." Vous pouvez penser cela. Cependant, la réflexion est une épée à double tranchant. Soyez prudent lors de la manipulation. ** Mais je vais le présenter. ** **

Problèmes de réflexion

La réflexion dépend de la façon dont vous l'utilisez

Il existe également des problèmes tels que. ** Mais je vais le présenter. ** **

"Tester l'étendue privée avec JUnit" C'est parce qu'il est utilisé dans un but limité.

Revenir au sujet principal

Corrigeons la classe de test JUnit, qui regorge d'erreurs.

package jp.co.illmatics.sample;
/**
 *Classe à tester
 */
@SuppressWarnings("unused")
public class PrivateSample {

    private String field = "Hello field!";

    private final String finalField = "Hello final field!";

    private String doIt()    {
        return "Hello method!";
    }

    private class InnerClass {
        public InnerClass() {

        }
        public String getInnerMethod() {
            return "Hello inner method!";
        }
    }
}
package jp.co.illmatics.sample;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import org.junit.Test;

import junit.framework.TestCase;

/**
 *Classe d'essai
 */
public class PrivateSampleTest extends TestCase {

    PrivateSample privateSample = new PrivateSample();
    String expected = "";
    String actual = "";

    @Test
    public void testField() throws Exception {
        final String fieldName = "field";
        expected = "Hello field!";
        actual = (String) getFieldValue(privateSample, fieldName);
        assertEquals(expected, actual);
    }

    @Test
    public void testFinalField() throws Exception {
        final String finalFieldName = "finalField";
        expected = "Hello updated final Field!";
        actual = (String) getUpdatedFinalFieldValue(privateSample, expected, finalFieldName);
        assertEquals(expected, actual);
    }

    @Test
    public void testMethod() throws Exception {
        final String methodName = "doIt";
        expected = "Hello method!";
        actual = (String) getMethodValue(privateSample, methodName);
        assertEquals(expected, actual);
    }

    @Test
    public void testInnerClassMethod() throws Exception {
        final String innerClassName = "jp.co.illmatics.sample.PrivateSample$InnerClass";
        final String innerMethodName = "getInnerMethod";
        expected = "Hello inner method!";
        actual = (String) getInnerClassMethod(privateSample, innerClassName, innerMethodName);
        assertEquals(expected, actual);
    }

    private Object getFieldValue(PrivateSample privateSample, String fieldName)
            throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException,
            SecurityException {
        return getPrivateField(privateSample, fieldName).get(privateSample);
    }

    private Field getPrivateField(PrivateSample privateSample, String fieldName)
            throws NoSuchFieldException, SecurityException, IllegalArgumentException,
            IllegalAccessException {
        Class<?> clazz = privateSample.getClass();
        Field field = clazz.getDeclaredField(fieldName);
        field.setAccessible(true);
        return field;
    }

    private Object getUpdatedFinalFieldValue(PrivateSample privateSample, String newValue,
            String fieldName) throws NoSuchFieldException, SecurityException,
                    IllegalArgumentException, IllegalAccessException {
        Field finalField = getPrivateField(privateSample, fieldName);
        finalField.set(privateSample, newValue);
        return finalField.get(privateSample);
    }

    private Object getMethodValue(PrivateSample privateSample, String name)
            throws NoSuchMethodException, SecurityException, IllegalAccessException,
            IllegalArgumentException, InvocationTargetException {
        Method doIt = PrivateSample.class.getDeclaredMethod(name);
        doIt.setAccessible(true);
        return doIt.invoke(privateSample);
    }

    private Object getInnerClassMethod(PrivateSample parent, String classFullName,
            String methodName) throws ClassNotFoundException, NoSuchMethodException,
                    SecurityException, InstantiationException, IllegalAccessException,
                    IllegalArgumentException, InvocationTargetException {
        ClassLoader loader = ClassLoader.getSystemClassLoader();
        Class<?> innerClazz = loader.loadClass(classFullName);
        Constructor<?> constructor = innerClazz.getDeclaredConstructor(parent.getClass());
        constructor.setAccessible(true);
        Object innerObj = constructor.newInstance(parent);
        return innerClazz.getDeclaredMethod(methodName).invoke(innerObj);
    }
}

resolved.png J'ai pu le réparer.

testStart.png Tester

testSucceeded.png C'est fait.

Recommended Posts

Comment tester l'étendue privée avec JUnit
[Java] Comment tester s'il est nul dans JUnit
Comment tester les interruptions pendant Thread.sleep avec JUnit
Comment tester une méthode privée qui prend un tableau ou un argument de longueur variable dans JUnit
[Java] Tester des méthodes privées avec JUnit
Comment filtrer JUnit Test dans Gradle
Faites un test unitaire avec Junit.
JUnit 5: Comment écrire des cas de test dans enum
Comment écrire du code de test avec la certification de base
Tester l'API Web avec junit
Comment faire un test unitaire avec JVM sur une source à l'aide de RxAndroid
Comment utiliser JUnit (débutant)
Comment numéroter (nombre) avec html.erb
Comment mettre à jour avec activerecord-import
Comment effectuer UT avec Excel en tant que données de test avec Spring Boot + JUnit5 + DBUnit
Tester les méthodes privées dans JUnit
Comment écrire Junit 5 organisé
[Création] Comment utiliser JUnit
[Rails] Comment utiliser Scope
Comment exécuter uniquement des fichiers spécifiques avec le test de rake de gem
Comment effacer l'image de test après avoir exécuté le test Rspec à l'aide de CarrierWave
[Java] Je souhaite tester l'entrée standard et la sortie standard avec JUnit
Comment utiliser scope (JSP & Servlet)
Comment faire un test unitaire de Spring AOP
Comment démarrer avec Slim
Comment entourer n'importe quel caractère avec "~"
Comment utiliser mssql-tools avec Alpine
Contrôleur de cadre de test Spring avec Junit
Comment démarrer Camunda avec Docker
Comment recadrer une image avec libGDX
Comment ajuster TextPosition avec l'extension de clavier iOS
Comment partager des fichiers avec Docker Toolbox
Comment compiler Java avec VsCode & Ant
[Java] Résumez comment comparer avec la méthode equals
[Android] Comment gérer les thèmes sombres
Comment utiliser BootStrap avec Play Framework
Comment changer d'images miniatures avec JavaScript
[Note] Comment démarrer avec Rspec
Comment faire un contrôle basé sur l'API avec cancancan
Comment fixer la date système dans JUnit
Comment réaliser le téléchargement de fichiers avec Feign
Comment mettre à jour les modèles associés avec accepte_nested_attributes_for
Comment définir JAVA_HOME avec l'appassembler-maven-plugin de Maven
Comment gérer les erreurs de connexion avec l'appareil
Comment supprimer des données avec une clé externe
Le test JUnit 5 Gradle génère une erreur avec l'annotation Lombok
Comment surveiller nginx avec docker-compose avec datadog
Présentation du test Java automatisé avec JUnit 5 + Gradle
Comment gérer les actifs de précompilation a échoué.
[SpringBoot] Comment écrire un test de contrôleur
Comment réaliser le téléchargement de fichiers avec Feign
Comment exécuter Blazor (C #) avec Docker
Comment créer un environnement Rails 6 avec Docker