@ До и @ После исключения - PullRequest
2 голосов
/ 02 ноября 2010

Я пишу несколько тестов для моего DAO, и поскольку во многих тестах используется тестовый объект, который сохраняется в моей базе данных, я создал метод setup () и teardown () с аннотациями @Before и @After соответственно, чтобы избежать избыточного кода, но один из тестов, на самом деле тот, который действительно не нуждается в тестовом объекте, вызывает метод в DAO, который содержит вызов getCurrentSession (). Clear () (это метод, который использует ScrollableResults чтобы получить данные из базы данных в пакетном режиме и избежать заполнения памяти, она вызывает flush () и clear () через каждые 50 строк. Это создает проблему, поскольку clear () фактически удаляет тестовый объект, созданный в setup () из сеанса, поэтому при вызове teardown () я получаю сообщение об ошибке:

org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [nl.ru.cmbi.pdbeter.core.model.domain.PDBEntry#395]

Есть ли способ сказать JUnit не использовать setup () и teardown () в этом тесте, или лучше поместить все тесты, которые на самом деле не нуждаются в setup () и teardown (), в новый тестовый класс?

Ответы [ 3 ]

6 голосов
/ 02 ноября 2010

Прежде всего, да, имеет смысл выделить тесты, которые не нуждаются в поведении @Before или @After в отдельном тесте.

Во-вторых, вы можете захотеть взглянуть на поддержку Spring Framework для запуска модульных тестов в транзакции базы данных , которая автоматически откатывается в конце каждого теста, так что вам не нужно когда-нибудь беспокоиться о некоторых тестах, влияющих на состояние внешнего ресурса, или задавать вопросы о том, какие тесты выполняются в каждом порядке и т. д. Объедините это с базой данных в памяти (например, HSQL ), и вы выиграете даже не нужно беспокоиться о наличии работающей базы данных, чтобы сделать вашу сборку намного более переносимой.

2 голосов
/ 02 ноября 2010

JUnit будет запускать все методы, отмеченные @Before и @After для каждого теста, поэтому вам нужно будет разделить ваши тесты на два класса.

0 голосов
/ 04 ноября 2010

Определите свой собственный BlockJUnit4ClassRunner:

public class WithoutBeforeAfter extends BlockJUnit4ClassRunner {

    public WithoutBeforeAfter(Class<?> klass) throws InitializationError {
        super(klass);
    }

    @Override
    protected Statement withBefores(FrameworkMethod method, Object target, Statement statement) {
        if(method.getName().equals("methodNameIgnore@Before")){
            return statement;
        }else{
            return super.withBefores(method, target, statement);
        }
    }

    @Override
    protected Statement withAfters(FrameworkMethod method, Object target, Statement statement) {
        if(method.getName().equals("methodNameIgnore@After")){
            return statement;
        }else{
            return super.withAfters(method, target, statement);
        }
    }
}

Затем используйте его в своем тестовом примере:

@RunWith(value=WithoutBeforeAfter.class)

По крайней мере, он доступен в JUnit 4.8.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...