개체가 특정 유형이라고 가정


195

JUnit에서 객체가 클래스의 인스턴스라고 주장 할 수 있습니까? 여러 가지 이유로 테스트에서 유형을 확인하려는 객체가 있습니다. Object1의 유형입니까 아니면 Object2의 유형입니까?

현재 나는 :

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

이것은 작동하지만 더 표현하는 방법이 있는지 궁금합니다.

예를 들면 다음과 같습니다.

assertObjectIsClass(myObject, Object1);

나는 이것을 할 수있다 :

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

좀 더 우아하고 유동적 인 방식으로 객체 유형을 테스트 할 수있는 특정 어설 션 방법이 있습니까?


15
당신은 알고 계십니까 assertTrue(myObject instanceof Object1);assertEquals(myObject.class, Object1.getClass());실제로 다른 테스트입니까? 첫 번째는 myObject를의 하위 클래스의 인스턴스로 허용 Object1하지만 나중에는 그렇지 않습니다.
Erich Kitzmueller

@ammoQ 아주 좋은 지적입니다. 나는 서브 클래스를 생각하지 않았다. 클레임에 감사드립니다
RNJ

1
maba가 지적했듯이 Hamcrest 사용을 고려하십시오. 이것은 당신이 더 나은 작업 시험을 할 수 있도록하는 것 이상입니다. Hamcrest는 또한 표준보다 훨씬 더 나은 오류 로깅을 제공합니다 assertTrue. assertTrue단지 말을 expected true got falseHamcrest 말 것expected instanced of XYZ, got instance of ABC
존 B에게

답변:


253

assertThatJUnit과 함께 제공 되는 메소드 및 Matcher를 사용할 수 있습니다 .

JUnit Matchers에 대해 설명하는 이 링크 를 살펴보십시오 .

예:

public class BaseClass {
}

public class SubClass extends BaseClass {
}

테스트:

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));
    }
}

4
다음은 사용중인 Matcher에 대한 링크입니다. hamcrest.org/JavaHamcrest/javadoc/1.3/org/hamcrest/…
John B

3
참고로 MatcherAssert.assertThat은 Assert.assertThat보다 더 잘 작동합니다 (오류가 발생하는 경우 더 나은 로깅 제공). 대신 사용하는 것이 좋습니다. hamcrest.org/JavaHamcrest/javadoc/1.3/org/hamcrest/…
John B

13
그것은 사소한 주장이며 예제에서 사실이 아니라면 컴파일 오류가 될 것입니다! 일반적으로 당신과 함께 클래스 계층 구조를 아래로 가고 싶어 instanceof: BaseClass subClass = new SubClass(); assertThat(subClass, isA(SubClass.class));하지만 있기 때문에 컴파일되지 않습니다 SubClass되지 않습니다 ? super BaseClass.
TWiStErRob

3
난 당신이를 변경하려고 ... 여기서 말하려고하는 것을 이해하지 @TWiStErRob instanceOf(BaseClass.class)instanceOf(String.class)당신은 그것을 잘 컴파일 것을 볼 수 있지만 던져 않고 AssertionError가있을 것입니다.
maba

1
@maba, 그는 어떤 이유로 클래스를 캡처하는 isA에 대해 이야기하고 있습니다 (인스턴스의 역할 Class<T>대신 Class<?>). 클래스를 캡처하기 때문에 인스턴스와 호환되지 않는 클래스로 isA를 수행하면 컴파일 시간 오류가 발생합니다. github.com/hamcrest/JavaHamcrest/issues/39
Vsevolod Golovanov

46

때문에 assertThat이는 이전의 대답은 지금은 올바른 솔루션을 게시하고, 사용되지 않습니다했다 :

assertTrue(objectUnderTest instanceof TargetObject);


2
objectUnderTest가 TargetObject의 서브 클래스 인 경우에도 여전히 결과가 발생 true합니까? 실제 유형을 테스트하고 싶다고 생각합니다.
EricG

나는 이것이 정답이 아니라고 생각합니다. 원래 질문은 객체의 정확한 유형을 구체적으로 확인하는 것을 요구하는 것이 었습니다. 이 솔루션은 (위의 @EircG에서 언급 한 바와 같이) 그렇지 않으며, 사용자가 원래 질문을하는 경우에도 제공되었으므로 "올바른"답변은 아닙니다. 정답은 Franklin Yu 답변을 확인하십시오.
kekko12

글쎄, 그것은 Franklin의 대답에 대해 @EricG가 예라고 언급 한 단점이 있습니다. 방금 보았습니다. 나에게 이해가되지 않았기 때문에 Junit5로 프로젝트를 테스트했습니다. instanceof와 같은 구문이나 InstanceOf! 메소드는 없습니다. 그는 완전히 틀렸다. 나는 여전히 내 대답을 기다리고 있으며, 입증 된 바와 같이, 그것을 찬성했던 적어도 30 명에게 도움이되었다! (나는 당신이 downvoted한다고 가정합니다).
Carmageddon

@ kekko12 내 대답은 정확한 유형도 확인하지 않습니다. 이 답변과 비슷한 하위 클래스를 허용합니다. 답변을 업데이트하기 위해 답변을 업데이트했습니다. 해당 부분을 눈치 채지 못해서 죄송합니다. 대부분의 어설 션 라이브러리에는 정확한 평등이 포함되어 있지 않다고 생각합니다.
Franklin Yu

@Carmageddon hamcrest 어설 션 가져 오기를 사용 하면 Franlin Yu의 답변이 제대로 작동합니다 .```import static org.hamcrest.CoreMatchers.instanceOf; ```그의 코드 샘플 당 ss. 나는 Franklin의 대답을 간과했지만 인정하지만 사실이 두 가지 대답은 기능적으로 동일하므로 결국 선호의 문제 일 것입니다.
kekko12

23

JUnit 5 솔루션

설명서는 다음과 같이 말합니다.

그러나 JUnit Jupiter의 org.junit.jupiter.Assertions클래스는 assertThat()JUnit 4의 org.junit.Assert클래스에서 Hamcrest를 허용하는 메소드와 같은 메소드를 제공하지 않습니다 Matcher. 대신 개발자는 타사 어설 션 라이브러리에서 제공하는 매처에 대한 기본 제공 지원을 사용하는 것이 좋습니다.

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));
    }

}

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);
    }

}

instanceof이는 하위 클래스를 허용하는 것과 유사한 동작을 테스트한다고 가정합니다 . 정확히 같은 유형을 원한다면 질문에서 언급 한 것처럼 두 클래스를 동일하게 주장하는 것보다 더 좋은 방법은 없습니다.


1
어떤 의미에서 원본 assertThat()은 Hamcrest로 연기되므로 JUnit은 타사 어설 션 라이브러리와도 작동합니다.
Franklin Yu

방금이 답변을 테스트했는데 정확하지 않으며 여러 컴파일 오류가 발생합니다. 잘못된 표현 시작, 잘못된 유형 시작, ';' 예상 된 것입니다. 즉, assertThat 매처에 대한 두 번째 매개 변수는 "instanceof (BaseClass.class)"일 수 없습니다! 사실, 당신은 그것을 정확하게 입력하지 않았고, 사용한 구문은 약간 다릅니다- "InstanceOf ("-함수 호출! 실제로는 그런 함수가 없습니다 ... 누군가가 테스트 했습니까? 수동으로 보인다? 테스트없이 입력
Carmageddon

@ Carmageddon 나는 Hamcrest와 AssertJ에 대한 두 가지 답변을 제공했습니다. 당신은 어느 것에 대해 이야기하고 있습니까?
Franklin Yu

@ Carmageddon 나는 당신이 Hamcrest 예제에 대해 이야기하고 있다고 생각하고 (사례를 염두에두고) 잘못 입력 instanceOf했습니다 instanceof. instanceOf함수 상태 instanceof입니다 자바 키워드 .
Franklin Yu

나는 물론 Hamcrest를 언급했으며 키워드와 함수를 모두 시도했지만 그 함수를 작성하는 방법을 알지
못했지만

3

Kotlin을위한 JUnit 5 솔루션!

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))
    }

}

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)
    }

}

1
이 매우 우아한 assertJ 솔루션에 감사드립니다
Aleks Nine
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.