Is it possible in JUnit to assert an object is an instance of a class? For various reasons I have an object in my test that I want to check the type of. Is it a type of Object1 or a type of Object2?
Currently I have:
assertTrue(myObject instanceof Object1);
assertTrue(myObject instanceof Object2);
This works but I was wondering if there is a more expressive way of doing this.
For example something like:
assertObjectIsClass(myObject, Object1);
I could do this:
assertEquals(myObject.class, Object1.getClass());
Is there a specific assert method that allows me to test a type of an object in a more elegant, fluid manner?
assertTrue(myObject instanceof Object1);
and assertEquals(myObject.class, Object1.getClass());
are actually different tests? The first accepts myObject being an instance of a subclass of Object1
, the later doesn't.
assertTrue
. assertTrue
would just say expected true got false
, Hamcrest would say expected instanced of XYZ, got instance of ABC
You can use the assertThat
method and the Matchers that comes with JUnit.
Take a look at this link that describes a little bit about the JUnit Matchers.
Example:
public class BaseClass {
}
public class SubClass extends BaseClass {
}
Test:
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));
}
}
Since assertThat
which was the old answer is now deprecated, I am posting the correct solution:
assertTrue(objectUnderTest instanceof TargetObject);
true
right? And I think you want to test the actual type.
Solution for JUnit 5
The documentation says:
However, JUnit Jupiter’s org.junit.jupiter.Assertions class does not provide an assertThat() method like the one found in JUnit 4’s org.junit.Assert class which accepts a Hamcrest Matcher. Instead, developers are encouraged to use the built-in support for matchers provided by third-party assertion libraries.
Example for 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));
}
}
Example for 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);
}
}
Note that this assumes you want to test behaviors similar to instanceof
(which accepts subclasses). If you want exact equal type, I don’t see a better way than asserting the two class to be equal like you mentioned in the question.
assertThat()
is deferred to Hamcrest, so that JUnit also works with third-party assertion libraries.
instanceOf
as instanceof
(mind the case). instanceOf
is a function while instanceof
is a Java keyword.
Solution for JUnit 5 for Kotlin!
Example for 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))
}
}
Example for 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)
}
}
Solution for JUnit for Kotlin
What worked for me:
assert(obj is ClassName)
for exmaple
assert(obj is User)
NOTE: assert is coming from AssertionsJVM.kt
file
Experimental Solution for JUnit 5.8
In Junit 5.8, the experimental assertInstanceOf()
method was added, so you don't need Hamcrest or AssertJ anymore. The solution is now as simple as:
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
import org.junit.Test;
public class InstanceOfTest {
@Test
public void testInstanceOf() {
SubClass subClass = new SubClass();
assertInstanceOf(BaseClass.class, subClass);
}
}
Success story sharing
instanceof
:BaseClass subClass = new SubClass(); assertThat(subClass, isA(SubClass.class));
, but it doesn't compile becauseSubClass
is not? super BaseClass
.instanceOf(BaseClass.class)
toinstanceOf(String.class)
and you'll see that it compile just fine but there will be an AssertionError thrown.Class<T>
instead ofClass<?>
(which is what instanceOf does). Since it captures the class, it would be a compile time error to do isA with a class incompatible to the instance. github.com/hamcrest/JavaHamcrest/issues/39