Bir nesnenin belirli bir tür olduğunu iddia etme


195

JUnit'te bir nesnenin bir sınıf örneği olduğunu iddia etmek mümkün müdür? Çeşitli nedenlerle testimde türünü kontrol etmek istediğim bir nesne var. Bu bir tür Object1 mi yoksa bir tür Object2 mi?

Şu anda var:

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

Bu işe yarıyor ama bunu yapmanın daha etkileyici bir yolu olup olmadığını merak ediyordum.

Örneğin:

assertObjectIsClass(myObject, Object1);

Bunu yapabilirdim:

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

Bir nesnenin türünü daha zarif ve akıcı bir şekilde test etmeme izin veren belirli bir iddia yöntemi var mı?


15
Bunun farkında mısınız assertTrue(myObject instanceof Object1);ve assertEquals(myObject.class, Object1.getClass());aslında farklı testler misiniz? Birincisi myObject öğesinin bir alt sınıf örneği olduğunu kabul eder Object1, daha sonra kabul etmez.
Erich Kitzmueller

@ammoQ Çok iyi bir nokta. Alt sınıfları düşünmedim. Açıklık için teşekkürler
RNJ 13:04

1
maba'nın işaret ettiği gibi Hamcrest'i kullanmayı düşünün. Bu, daha iyi bir çalışma testine sahip olmanızdan daha fazlasıdır. Hamcrest ayrıca standart arızadan çok daha iyi bir kayıt sağlar assertTrue. assertTruesadece söyleyebilirim expected true got false, Hamcrest söylerdiexpected instanced of XYZ, got instance of ABC
John B

Yanıtlar:


253

assertThatJUnit ile gelen yöntemi ve Eşleştiricileri kullanabilirsiniz .

JUnit Eşleştiricileri hakkında biraz bilgi veren bu bağlantıya bir göz atın .

Misal:

public class BaseClass {
}

public class SubClass extends BaseClass {
}

Ölçek:

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
Kullanılan Matcher'ın
John B

3
FYI, MatcherAssert.assert Assert.assertThat'tan daha iyi davranıyor (hata durumunda daha iyi günlük kaydı sağlıyor). Bunun yerine kullanmanızı öneririm. hamcrest.org/JavaHamcrest/javadoc/1.3/org/hamcrest/…
John B

13
Bu önemsiz bir iddia ve örnekte doğru değilse derleme hatası olur! Genellikle ile sınıf hiyerarşisine gitmek istersiniz instanceof: BaseClass subClass = new SubClass(); assertThat(subClass, isA(SubClass.class));ancak derlenmez çünkü SubClassdeğildir ? super BaseClass.
TWiStErRob

3
Sana değiştirmeye çalışın ... Burada söylemeye çalışıyorsun anlamıyorum @TWiStErRob instanceOf(BaseClass.class)için instanceOf(String.class)ve bunu gayet güzel derlemek görürsünüz ama atılmış bir AssertionError olacaktır.
maba

1
maba, bir sebepten ötürü sınıfı ele geçiren isA hakkında konuşuyor, Class<T>yerine kabul ediyor Class<?>(bu exampleOf'un yaptığı şey). Sınıfı yakaladığından, isA örneğiyle uyumsuz bir sınıfla derleme zamanı hatası olur. github.com/hamcrest/JavaHamcrest/issues/39
Vsevolod Golovanov

46

Bu assertThateski cevap şimdi kaldırıldığından beri , doğru çözümü gönderiyorum:

assertTrue(objectUnderTest instanceof TargetObject);


2
objectUnderTest TargetObject öğesinin bir alt sınıfı ise, bu yine de truesağa neden olur mu? Sanırım gerçek türü test etmek istiyorsunuz.
EricG

Bunun doğru cevap olmadığını hissediyorum. Orijinal soru, nesnenin tam tipini kontrol eden bir şey soruyordu. Bu çözümler (yukarıdaki @EircG tarafından belirtildiği gibi) bunu yapmaz ve hatta orijinal olarak soruyu soran kullanıcı tarafından bile sağlanmıştır, bu yüzden kesinlikle "doğru" cevap imo değildir. Doğru cevap için lütfen Franklin Yu cevabını kontrol edin.
kekko12

Peki, @EricG'in evet, Franklin'in cevabı hakkında bahsettiği dezavantajı var - sadece ona baktım ve bana mantıklı gelmedi, bu yüzden sadece Junit5 ile projemde test ettim - yanlış! instanceof için böyle bir sözdizimi veya InstanceOf! Tamamen yanlış. Cevabımın yanında duruyorum ve kanıtlandığı gibi, bunu iptal eden en az 30 kişiye yardımcı oldu! (Sanırım aşağı düştünüz).
Carmageddon

@ kekko12 Cevabım da tam türü kontrol etmiyor; bu cevaba benzer alt sınıfı kabul eder. Cevabımı ele almak için cevabımı güncelledim; söz konusu kısmı fark etmediğim için üzgünüm. Bence tam eşitlik çoğu iddia kütüphanesinde yer almıyor çünkü sık kullanılmıyor.
Franklin Yu

Franlin Yu'dan cevap @Carmageddon iyi çalışır eğer İçe hamcrest iddiasını kullanın: `` `ithal statik org.hamcrest.CoreMatchers.instanceOf; `` Kod örnekleri başına ss. Franklin cevabını göz ardı etsem de itiraf ediyorum ve aslında bu 2 cevap işlevsel olarak eşdeğerdir, bu yüzden sanırım sonunda sadece bir tercih meselesi.
kekko12

23

JUnit 5 için çözüm

Belgeler diyor ki:

Ancak, JUnit Jupiter'in org.junit.jupiter.Assertionssınıfı, assertThat()JUnit 4'ün org.junit.Assertsınıfında bulunan ve bir Hamcrest'i kabul eden bir yöntem sağlamaz Matcher. Bunun yerine, geliştiricilerin, üçüncü taraf iddia kütüphaneleri tarafından sağlanan eşleştiriciler için yerleşik desteği kullanmaları önerilir.

Hamcrest için örnek :

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

}

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

}

Bunun, benzer instanceof(alt sınıfları kabul eden) davranışları test etmek istediğinizi varsaydığını unutmayın . Tam olarak eşit tip istiyorsanız, iki sınıfın soruda belirttiğiniz gibi eşit olduğunu iddia etmekten daha iyi bir yol göremiyorum.


1
Bir anlamda, orijinal assertThat(), Hamcrest'e ertelenir, böylece JUnit, üçüncü taraf iddia kütüphaneleriyle de çalışır.
Franklin Yu

Ben sadece bu cevabı test ettim, doğru DEĞİLDİR ve çoklu derleme hatalarına yol açar: Yasadışı ifade başlangıcı, yasadışı tür başlangıcı, ';' beklenen ... Diğer bir deyişle, assertThat eşleştiricisine ikinci parametreniz "instanceof (BaseClass.class)" olamaz! Aslında, doğru bir şekilde bile yazmadınız, kullandığınız sözdizimi biraz farklı - "InstanceOf (" - bir işlev çağrısı olarak! Aslında böyle bir işlev yok ... hatta hiç kimse tarafından test edildi mi? herhangi bir test yapılmadan yazılmıştır
Carmageddon

@Carmageddon Biri Hamcrest ve diğeri AssertJ için olmak üzere iki cevap verdim. Hangisi hakkında konuşuyorsunuz?
Franklin Yu

Sana hamcrest Örneğin bahsediyoruz şüpheli ve @Carmageddon özlüyorum-daktilo instanceOfolarak instanceof(dava mind). instanceOfolan bir fonksiyon iken instanceofolan bir Java anahtar kelime .
Franklin Yu

Hamcrest'e elbette birinden bahsettim ve bunu nasıl yazdığınızı fark ettikten sonra her iki anahtar kelimeyi VE bir işlev olarak denedim - böyle bir işlev yok ...
Carmageddon

3

Kotlin için JUnit 5 için çözüm!

Hamcrest için örnek :

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

}

Örnek 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
Bu çok şık assertJ çözümü için teşekkürler
Aleks Nine
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.