オブジェクトが特定のタイプであることを表明する


195

JUnitでオブジェクトがクラスのインスタンスであることを表明することは可能ですか?さまざまな理由で、タイプを確認したいオブジェクトがテストに含まれています。Object1のタイプですか、それともObject2のタイプですか?

現在私は持っています:

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

これは機能しますが、もっと表現力豊かな方法があるかどうか疑問に思っていました。

たとえば次のようなもの:

assertObjectIsClass(myObject, Object1);

私はこれを行うことができます:

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

よりエレガントで流動的な方法でオブジェクトのタイプをテストできる特定のassertメソッドはありますか?


15
あなたはことを知っているassertTrue(myObject instanceof Object1);し、assertEquals(myObject.class, Object1.getClass());実際には異なるテストですか?最初はmyObjectをのサブクラスのインスタンスとして受け入れますが、後者は受け入れObject1ません。
Erich Kitzmueller 2012

@ammoQ非常に良い点です。サブクラスについては考えませんでした。明確化に感謝
RNJ

1
マバが指摘するように、ハムクレストの使用を検討してください。これは、テストをより効果的に行うためだけのものではありません。Hamcrestはまた、標準よりもはるかに優れた障害のロギングを提供しますassertTrueassertTrueと言うだけでexpected true got false、ハムクレストは言うだろうexpected instanced of XYZ, got instance of ABC
ジョンB

回答:


253

assertThatJUnitに付属するメソッドとマッチャーを使用できます。

JUnit Matcherについて少し説明しているこのリンクをご覧ください。

例:

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
使用されているマッチャーへのリンクは次のとおり
John B

3
ちなみに、MatcherAssert.assertThatはAssert.assertThatよりも適切に動作します(エラーが発生した場合のロギングが向上します)。代わりに使用することをお勧めします。hamcrest.org/JavaHamcrest/javadoc/1.3/org/hamcrest/...
ジョンB

13
これは取るに足らないアサーションであり、例でtrueでない場合はコンパイルエラーになります。通常、クラス階層をinstanceofBaseClass subClass = new SubClass(); assertThat(subClass, isA(SubClass.class));で下に行きたいのですが、がないのでコンパイルされSubClassません? super BaseClass
TWiStErRob

3
@TWiStErRobここで何を言おうとしているのか理解できません...をに変更しinstanceOf(BaseClass.class)てみてください。instanceOf(String.class)コンパイルが正常に行われますが、AssertionErrorがスローされます。
maba、2014

1
@maba、彼は何らかの理由でisAについて話しています。これはクラスをキャプチャし、Class<T>代わりに受け入れますClass<?>(これはinstanceOfが行うことです)。クラスをキャプチャするため、インスタンスと互換性のないクラスでisAを実行すると、コンパイル時エラーになります。github.com/hamcrest/JavaHamcrest/issues/39
Vsevolod Golovanov

46

以来assertThat、古い答えが廃止され、私は正しい解決策を掲載していました。

assertTrue(objectUnderTest instanceof TargetObject);


2
objectUnderTestがTargetObjectのサブクラスである場合、これはtrue正しい結果になりますか?実際のタイプをテストしたいと思います。
EricG 2018年

これは正解ではないと思います。元の質問は、オブジェクトの正確なタイプを具体的に確認するものを求めていました。このソリューションは(上記の@EircGで言及されているように)それを行わず、元々質問をしたユーザーによって提供されていたので、「正しい」答えもありません。正解はフランクリン・ユーの解答をチェックしてください。
kekko12

まあ、それはフランクリンの答えについて@EricGがイエスと述べた欠点を持っています-私はそれを見て、それは私にとって意味がなかったのでJunit5で私のプロジェクトでテストしました-それは間違っています!! instanceofにはそのような構文はなく、InstanceOf!というメソッドもありません。彼は完全に間違っています。私は自分の答えをじっと見守っていて、証明されているように、それを賛成した少なくとも30人の人々に役立ちました。(私はあなたが反対票を投じたと思います)。
カルマゲドン

@ kekko12私の答えは正確なタイプもチェックしません。この回答と同様のサブクラスを受け入れます。これに対処するために回答を更新しました。問題のこの部分に気づかなかったのは残念です。正確な等価性は頻繁に使用されないため、ほとんどのアサーションライブラリには含まれていません。
フランクリン・ユー

@Carmageddon hamcrestアサーションインポートを使用する場合、Franlin Yuからの回答は正常に機能します。 `` `import static org.hamcrest.CoreMatchers.instanceOf; `` `彼のコードサンプルごとのss。私はフランクリンの回答を見落としましたが、実際にはこれら2つの回答は機能的に同等であるため、結局は好みの問題だと思います。
kekko12

21

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(サブクラスを受け入れる)と同様の動作をテストすることを想定していることに注意してください。完全に等しい型が必要な場合、質問で述べたように2つのクラスが等しいと主張するよりも良い方法はありません。


1
ある意味で、オリジナルassertThat()はHamcrestに委ねられているため、JUnitはサードパーティのアサーションライブラリでも動作します。
フランクリン・ユー、

私はこの答えをテストしましたが、正しくありません。複数のコンパイルエラーが発生します。式の開始が不正です。型の開始が不正です; ';' 期待しています...つまり、assertThatマッチャーへの2番目のパラメーターは「instanceof(BaseClass.class)」にはできません!実際、あなたはそれを正しく入力していませんでした、使用した構文は少し異なります-"InstanceOf("--関数呼び出しとして!そのような関数は実際にはありません...それは誰かによってもテストされましたか?それは手動で行われたようですテストなしで入力
Carmageddon '9/09/19

@Carmageddon私は2つの回答を提供しました。1つはHamcrest、もう1つはAssertJです。どちらについて話しているのですか?
フランクリンユー

私はあなたがHamcrest例について話している疑いがあり、@Carmageddon欠場型付けされたinstanceOfとして、instanceof(ケースを気)。instanceOf関数instanceofあり、はJavaキーワードです。
フランクリンユー

もちろん私はHamcrestの1つを参照し、それを書いた方法に気付いた後、キーワードと関数の両方を試しました-そのような関数はありません...
Carmageddon

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.