Как запустить метод типа tearDown для конкретного теста в классе JUnit с несколькими тестами? - PullRequest
1 голос
/ 18 февраля 2011

У меня есть класс junit testCase с несколькими методами тестирования (как требование, мы не хотим создавать отдельный класс для каждого теста.)

Я хочу создать метод типа tearDown для КАЖДОГО метода теста, который будет запускаться специально для этого теста. Не для ВСЕХ испытаний.

Моя проблема в том, что во многих тестах я вставляю запись в базу данных, проверяю ее и удаляю после проверки. Но, если тест не пройден в середине пути, контроль не доходит до конца, моя фиктивная запись не удаляется.

Я думаю, что только ОДИН tearDown() разрешен для одного класса, и эти tearDown() не знают, какой объект / запись я создал или вставил и что удалить !!!

Я хочу создать метод tearDown() или @After только для одного конкретного теста. Что-то вроде finally{} в Java для каждого метода.

Например:

 public class TestDummy extends TestCase {

        public void testSample1(){
                     InsertSomeData1();

         assertFalse(true);
         runTearDown1();
    }

    public void testSample2(){
                     InsertSomeData2();
         assertFalse(true);
                     runTearDown2();

    }

      public void runTearDown1(){
      deleteDummyDatafromTestSample1....
     }

      public void runTearDown2(){
      deleteDummyDatafromTestSample2....
     }

}

Здесь управление никогда не перейдет к runTearDown1() или runTearDown2(), и у меня нет ни одного распространенного tearDown(), потому что он не будет знать, какие данные я вставил и какие специфичны для каждого метода.

Ответы [ 4 ]

1 голос
/ 19 февраля 2011

Вы могли бы получить что-то вроде этого:

interface DBTest {
  void setUpDB();
  void test();
  void tearDownDB();
}

class DBTestRunner {
  void runTest(DBTest test) throws Exception {
    test.setUpDB();
    try {
      test.test();
    } finally {
      test.tearDownDB();
    }
  }
}

public void test48() throws Exception {
  new DBTestRunner().runTest(new DBTest() {
    public void setUpDB() {...}
    public void test() {...}
    public void tearDownDB() {...}
  });
}
1 голос
/ 18 февраля 2011

Кажется, что ваш тест основан на фиксированной базе данных, и будущие тесты прервутся, если ваш текущий тест прервется. Я бы порекомендовал не сосредоточиться на этой конкретной проблеме (метод tearDown для конкретного теста, который выполняется для каждого теста), а на вашей основной проблеме - тестах Боркена. Перед выполнением теста он всегда должен работать с чистой базой данных, и так должно быть в каждом тесте. Прямо сейчас ваш первый тест связан со вторым (через базу данных).

Правильный подход заключается в том, что вы воссоздаете свою базу данных перед каждым тестом или, по крайней мере, восстанавливаете ее до базового состояния. В этом случае вам понадобится такой тест:

public class TestDummy {

    // this code runs (once) when this test class is run.
    @BeforeClass
    public void setupDatabase() {
        // code that creates the database schema
    }

    // this code runs after all tests in this class are run.
    @AfterClass
    public void teardownDatabase() {
        // code that deletes your database, leaving no trace whatsoever.
    }

    // This code runs before each test case. Use it to, for example, purge the
    // database and fill it with default data.
    @Before
    public void before() {

    }

    // You can use this method to delete all test data inserted by a test method too.
    @After
    public void after() {

    }

    // now for the tests themselves, we should be able to assume the database will
    // always be in the correct state, independent from the previous or next test cases.
    @Test
    public void TestSample2() {
       insertSomeData();
       assertTrue(someData, isValid());
    }
}

Отказ от ответственности: тесты JUnit 4 (с использованием аннотаций), возможно, не являются правильными аннотациями, могут даже не быть правильными ответами.

0 голосов
/ 19 февраля 2011

Использовать MethodRule:

public class MyRule implements MethodRule {

    @Override
    public Statement apply(final Statement base, FrameworkMethod method, Object target) {
        return new Statement() {
            @Override
            public void evaluate() throws Throwable {
                try {
                    base.evaluate();
                } catch (AssertionError e) {
                    doFail();
                } finally {
                    doAnyway();
                }
            }
        };
    }
}

Затем объявите это в своем тестовом классе:

public class TestDummy{
   public MethodRule rule = new MyRule();
......
}
0 голосов
/ 19 февраля 2011

@ iluxa. Gr8 .. Ваше решение идеально подходит !!! В одном тестовом классе я создал два теста test48 и test49 (как и требовалось в моем коде выше testSample1 и testSample2) и альт! каждый метод тестирования теперь получает свои собственные setup () и tearDown. Только это решение выглядит немного сложным, так как нужно использовать DBTestRunner в каждом методе, но лучшего решения я не вижу. Я думал, что у Junit может быть какое-то прямое решение. как @After или tearDown () с некоторым параметром или чем-то. Ткс много.

...