Afirmar que un objeto es un tipo específico

195

¿Es posible en JUnit afirmar que un objeto es una instancia de una clase? Por varias razones, tengo un objeto en mi prueba que quiero verificar el tipo de. ¿Es un tipo de Object1 o un tipo de Object2?

Actualmente tengo:

assertTrue(myObject instanceof Object1);
assertTrue(myObject instanceof Object2);

Esto funciona, pero me preguntaba si hay una forma más expresiva de hacerlo.

Por ejemplo algo como:

assertObjectIsClass(myObject, Object1);

Yo podría hacer esto:

assertEquals(myObject.class, Object1.getClass());

¿Existe un método de afirmación específico que me permita probar un tipo de objeto de una manera más elegante y fluida?

RNJ
fuente
15
¿Eres consciente de eso assertTrue(myObject instanceof Object1);y en assertEquals(myObject.class, Object1.getClass());realidad son pruebas diferentes? El primero acepta que myObject es una instancia de una subclase de Object1, el segundo no.
Erich Kitzmueller
@ammoQ Muy buen punto. No pensé en subclases. Gracias por la aclaración
RNJ
1
Como señala Maba, considere usar Hamcrest. Esto es más que solo para que tenga una mejor prueba de trabajo. Hamcrest también proporciona un registro de la falla mucho mejor que el estándar assertTrue. assertTruediría expected true got false, Hamcrest diríaexpected instanced of XYZ, got instance of ABC
John B

Respuestas:

253

Puede usar el assertThatmétodo y los Matchers que vienen con JUnit.

Eche un vistazo a este enlace que describe un poco acerca de los JUnit Matchers.

Ejemplo:

public class BaseClass {
}

public class SubClass extends BaseClass {
}

Prueba:

import org.junit.Test;

import static org.hamcrest.CoreMatchers.instanceOf;
import static org.junit.Assert.assertThat;

/**
 * @author maba, 2012-09-13
 */
public class InstanceOfTest {

    @Test
    public void testInstanceOf() {
        SubClass subClass = new SubClass();
        assertThat(subClass, instanceOf(BaseClass.class));
    }
}
maba
fuente
44
Aquí está el enlace al Matcher que se está utilizando: hamcrest.org/JavaHamcrest/javadoc/1.3/org/hamcrest/…
John B
3
Para su información, MatcherAssert.assertThat se comporta mejor (proporciona un mejor registro en caso de errores) que Assert.assertThat. Recomiendo usarlo en su lugar. hamcrest.org/JavaHamcrest/javadoc/1.3/org/hamcrest/…
John B
13
¡Esa es una afirmación trivial y sería un error de compilación si no fuera cierto en el ejemplo! Por lo general, desea descender la jerarquía de clases con instanceof:, BaseClass subClass = new SubClass(); assertThat(subClass, isA(SubClass.class));pero no se compila porque SubClassno lo es ? super BaseClass.
TWiStErRob
3
@TWiStErRob No entiendo lo que estás tratando de decir aquí ... Intenta cambiar el instanceOf(BaseClass.class)a instanceOf(String.class)y verás que se compila muy bien, pero se lanzará un AssertionError.
maba
1
@maba, está hablando de isA por alguna razón, que captura la clase, acepta en Class<T>lugar de Class<?>(que es lo que hace instanciaOf). Como captura la clase, sería un error de tiempo de compilación hacer isA con una clase incompatible con la instancia. github.com/hamcrest/JavaHamcrest/issues/39
Vsevolod Golovanov
46

Dado assertThatque la respuesta anterior ahora está en desuso, estoy publicando la solución correcta:

assertTrue(objectUnderTest instanceof TargetObject);

Carmageddon
fuente
2
si objectUnderTest es una subclase de TargetObject, ¿esto seguirá siendo truecorrecto? Y creo que quieres probar el tipo real.
EricG
Siento que esta NO es la respuesta correcta. La pregunta original era pedir algo que verifique específicamente el tipo exacto del objeto. Esta solución no es eso (como se mencionó anteriormente en @EircG) e incluso ha sido proporcionada por el usuario que originalmente hizo la pregunta, por lo que definitivamente no es la respuesta "correcta" de la OMI. Para la respuesta correcta, verifique la respuesta de Franklin Yu.
kekko12
Bueno, tiene el inconveniente que @EricG mencionó que sí, sobre la respuesta de Franklin: solo la miré y no tenía sentido para mí, así que probé en mi proyecto con Junit5, ¡está mal! no existe tal sintaxis, por ejemplo, ni un método llamado InstanceOf! El esta totalmente equivocado. Todavía mantengo mi respuesta, y como se evidencia, ¡fue útil para al menos 30 personas que la votaron! (Asumo que has votado mal).
Carmageddon
@ kekko12 Mi respuesta tampoco comprueba el tipo exacto; acepta subclase similar a esta respuesta. He actualizado mi respuesta para abordarlo; Lamento no haber notado esta parte en cuestión. Creo que la igualdad exacta no se incluye en la mayoría de las bibliotecas de afirmaciones porque no se usa con frecuencia.
Franklin Yu
@Carmageddon La respuesta de Franlin Yu funciona bien si utiliza la importación de aserciones de Hamcrest: `` `` static static org.hamcrest.CoreMatchers.instanceOf; `` ss por sus ejemplos de código. Admito que pasé por alto la respuesta de Franklin y, de hecho, estas 2 respuestas son funcionalmente equivalentes, así que supongo que al final es solo una cuestión de preferencia.
kekko12
21

Solución para JUnit 5

La documentación dice:

Sin embargo, la org.junit.jupiter.Assertionsclase de JUnit Jupiter no proporciona un assertThat()método como el que se encuentra en la org.junit.Assertclase de JUnit 4 que acepta un Hamcrest Matcher. En cambio, se alienta a los desarrolladores a utilizar el soporte incorporado para los emparejadores proporcionados por bibliotecas de afirmaciones de terceros.

Ejemplo para Hamcrest :

import static org.hamcrest.CoreMatchers.instanceOf;
import static org.hamcrest.MatcherAssert.assertThat;

import org.junit.jupiter.api.Test;

class HamcrestAssertionDemo {

    @Test
    void assertWithHamcrestMatcher() {
        SubClass subClass = new SubClass();
        assertThat(subClass, instanceOf(BaseClass.class));
    }

}

Ejemplo para AssertJ :

import static org.assertj.core.api.Assertions.assertThat;

import org.junit.jupiter.api.Test;

class AssertJDemo {

    @Test
    void assertWithAssertJ() {
        SubClass subClass = new SubClass();
        assertThat(subClass).isInstanceOf(BaseClass.class);
    }

}

Tenga en cuenta que esto supone que desea probar comportamientos similares a instanceof(que acepta subclases). Si desea un tipo igual exacto, no veo una mejor manera que afirmar que las dos clases son iguales como mencionó en la pregunta.

Franklin Yu
fuente
1
En cierto sentido, el original assertThat()se difiere a Hamcrest, por lo que JUnit también funciona con bibliotecas de afirmaciones de terceros.
Franklin Yu
Acabo de probar esta respuesta, NO es correcta y conduce a múltiples errores de compilación: inicio de expresión ilegal, inicio de tipo ilegal, ';' esperado ... En otras palabras, su segundo parámetro para el aserción Ese emparejador, NO PUEDE ser "instanceof (BaseClass.class)"! De hecho, ni siquiera escribiste eso correctamente, la sintaxis que usaste es ligeramente diferente - "InstanceOf (" - como una llamada a la función. En realidad no existe tal función ... ¿fue probada por alguien? Parece haber sido manual mecanografiado sin ninguna prueba
Carmageddon
@Carmageddon Proporcioné dos respuestas, una para Hamcrest y la otra para AssertJ. De cual estas hablando?
Franklin Yu
@Carmageddon Sospecho que estás hablando del ejemplo de Hamcrest y escribiste mal instanceOfcomo instanceof(fíjate en el caso). instanceOfes una función mientras que instanceofes una palabra clave Java .
Franklin Yu
Me he referido a la Hamcrest por supuesto, y he intentado tanto de palabras clave y en función después de que me di cuenta de que eso es lo que lo escribió - no existe tal función ...
Carmageddon
3

¡Solución para JUnit 5 para Kotlin!

Ejemplo para Hamcrest :

import org.hamcrest.CoreMatchers
import org.hamcrest.MatcherAssert
import org.junit.jupiter.api.Test

class HamcrestAssertionDemo {

    @Test
    fun assertWithHamcrestMatcher() {
        val subClass = SubClass()
        MatcherAssert.assertThat(subClass, CoreMatchers.instanceOf<Any>(BaseClass::class.java))
    }

}

Ejemplo para AssertJ :

import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Test

class AssertJDemo {

    @Test
    fun assertWithAssertJ() {
        val subClass = SubClass()
        assertThat(subClass).isInstanceOf(BaseClass::class.java)
    }

}
Naruto Sempai
fuente
1
Gracias por esta solución afirmativa muy elegante
Aleks Nine