Pertanyaan Bagaimana cara menghindari pewarisan dalam kasus uji JUnit?


Saya memiliki sejumlah kasus uji coba di JUnit. Semuanya membutuhkan kode yang sama untuk dieksekusi di dalamnya @BeforeClass metode statis. Ini adalah duplikasi kode dan saya mencoba untuk menyingkirkannya. Cara kotor melakukan ini adalah dengan warisan. Apakah ada mekanisme lain di JUnit, yang dapat membantu?

PS. Saya menulis posting blog tentang subjek ini: http://www.yegor256.com/2015/05/25/unit-test-scaffolding.html


32
2017-07-16 04:14


asal


Jawaban:


Cara JUnit untuk menulis kode yang dapat digunakan kembali (alih-alih mewarisi darinya) adalah Aturan.

Lihat https://github.com/junit-team/junit/wiki/Rules

Ini contoh bodoh, tetapi Anda akan mengerti maksudnya.

import org.junit.rules.TestRule;
import org.junit.runners.model.Statement;
import org.junit.runner.Description;

public class MyTestRule implements TestRule {
  @Override
  public Statement apply(final Statement statement, Description description) {
    return new Statement() {
      public void evaluate() throws Throwable {
        // Here is BEFORE_CODE
        try {
          statement.evaluate();
        } finally {
          // Here is AFTER_CODE
        }
      }
    };
  }
}

Anda kemudian dapat menggunakan TestRule Anda seperti ini:

import org.junit.Rule;

public class MyTest {
    @Rule
    public MyTestRule myRule = new MyTestRule();
}

BEFORE_CODE dan AFTER_CODE akan dieksekusi di sekitar masing-masing metode pengujian Anda.

Jika Anda perlu menjalankan kode Anda hanya sekali per kelas, gunakan TestRule Anda sebagai @ClassRule:

import org.junit.ClassRule;

public class MyTest {
    @ClassRule
    public static MyTestRule myRule = new MyTestRule();
}

Sekarang, BEFORE_CODE dan AFTER_CODE akan dijalankan di setiap kelas tes Anda.

@Aturan bidang tidak statis, @ClassRule bidang ini.

@ClassRule dapat dideklarasikan dalam Suite juga.

Perhatikan bahwa Anda dapat mendeklarasikan beberapa aturan dalam kelas tes tunggal, begitulah cara Anda menyusun siklus hidup pengujian di suite tes, kelas tes, dan tingkat uji-metode.

Aturan adalah objek yang Anda instanciate di kelas tes Anda (secara statis atau tidak). Anda dapat menambahkan parameter contructor jika diperlukan.

HTH


31
2017-10-30 15:12



Jika metode tersebut adalah semacam utilitas, maka pisahkan ke kelas yang berbeda dengan metode statis dan panggil metode tersebut di @BeforeClass Anda.

Saya menekankan pada fakta yang tidak menggunakan warisan hanya karena menyelesaikan masalah Anda, menggunakannya ketika melakukan hal itu menciptakan rasa dalam hierarki kelas Anda.


4
2017-07-16 04:25



Anda dapat membuat pelari pengujian

public class MyTestRunner extends BlockJUnit4ClassRunner {
  @Override
  protected Object createTest() throws Exception {
     Object test = super.createTest();
     doStuff();
  }

  public void doStuff(){
     //common code
  }
}


@RunWith(MyTestRunner.class)
public class MyTest1{
    @Test
    public void test1(){
      //test method
    }
}

2
2017-08-23 06:05



Metode statis tidak diwarisi, jadi warisan bukanlah pilihan secara default. Jika Anda berarti Anda memindahkan metode ke kelas induk yang sama, maka itu tampaknya pilihan yang buruk karena Anda hanya mendapatkan satu induk di Java. Kelas pendukung tes dari beberapa jenis akan tampak lebih tepat. Mungkin juga Anda melihat kebutuhan akan a uji parameter.


1
2017-07-16 04:39



Tidak ada yang salah dengan pewarisan dalam kasus ini, itu sebenarnya satu-satunya cara untuk menghindari pengulangan kode ini di setiap subkelas. Fakta bahwa metode @BeforeClass harus dinyatakan statis di JUnit sangat disayangkan, tetapi itu seharusnya tidak menghentikan Anda. Perpanjang kelas dan Anda memiliki kode inisialisasi otomatis berjalan untuk Anda tanpa harus melakukan apa-apa.


1
2017-07-16 21:18



Jika masing-masing dan setiap kelas perlu memiliki @BeforeClass metode anotasi itu persis sama seperti yang lainnya, maka pewarisan tidak terasa bahwa salah untukku. Jika masing-masing metode inisialisasi ini hanya berbagi beberapa kode, Anda bisa membuat TestUtil kelas dengan beberapa perilaku bersama dan membuat panggilan ke perilaku bersama ini dari masing-masing @BeforeClass metode.


0
2017-07-16 04:26



Saya pikir jika kelas memiliki "adalah"Relasi, pewarisan itu wajar.

Jika kelas dasarnya MyBeforeClass yang mendefinisikan @BeforeClass metode, dan MyTestClass1 "adalah" MyBeforeClass, MyTestClass1 extends MyBeforeClass tidak apa-apa.


0
2017-07-16 04:41



Tergantung pada sifat dari kode pengaturan, Anda berpotensi menempatkan semua tes Anda dalam sebuah tes rangkaian dan memiliki kode pengaturan yang dijalankan di sana. Kelemahan untuk ini adalah bahwa Anda tidak dapat menjalankan tes secara individual (karena tes tergantung pada kode pengaturan).


0
2017-07-16 04:48