BeforeClass с помощью Spring транзакционные тесты

Слишком долго для комментария ... Поскольку документация немного расплывчата по этому вопросу ... (я смотрю на 1.7.1 в следующем)

jQuery.Event(event, props):

  • создает новый объект
  • устанавливает его свойство type для свойства события type.
  • устанавливает isDefaultPrevented посредством нормализованных вызовов все способы, чтобы проверить, предотвращено ли значение по умолчанию.
  • устанавливает originalEvent для ссылки на событие, которое вы прошли.
  • добавляет произвольный набор свойств, предоставляемых аргументом объекта props.
  • устанавливает метку времени.
  • помечает объект как «фиксированный».

То, что вы получаете, это в основном новый объект с несколькими дополнительными свойствами и ссылкой на исходное событие - без нормализации, кроме isDefaultPrevented.

jQuery.event.fix(event):

  • игнорирует объекты, которые уже были помечены как «исправленные».
  • делает доступную для записи копию (посредством jQuery.Event()) и нормализует свойства, упомянутые здесь .

ETA:

На самом деле, если присмотреться к коду, jQuery.event.fix() должно работать - так, как описано в @ Beetroot-Beetroot. Это все, что делает jQuery для создания объекта события jQuery в диспетчере событий.

10
задан Community 23 May 2017 в 12:15
поделиться

4 ответа

Я бы поддержал совет, что вы должны сделать каждый из ваших тестов автономным и, следовательно, выполнять всю настройку с помощью @Before, а не @BeforeClass.

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

 if(!databaseSetup) {
    ...set up the database
    databaseSetup=true;
    }

Не слишком навороченный, но он будет работать!

См. мой ответ здесь , где приведен пример теста транзакции Spring с аннотациями с использованием dbunit.

Надеюсь, это поможет!

2
ответ дан 4 December 2019 в 03:39
поделиться

Я не знаю, какую среду модульного тестирования вы используете, но для JUnit вы можете создать подкласс тестового класса AbstractTransactionalJUnit4SpringContextTests , который имеет метод executeSqlScript, который можно запустить в методе beforeclass или beforemethod. Я предпочитаю использовать BeforeMethod, поскольку это означает, что каждый из моих модульных тестов является автономным, даже если это означает, что мои модульные тесты выполняются немного медленнее.

1
ответ дан 4 December 2019 в 03:39
поделиться

Попробуйте использовать старые методы вместо причудливых аннотаций.

@BeforeClass
    public static void beforeClass() {
        ApplicationContext context = new ClassPathXmlApplicationContext(
        "applicationContext.xml");
                  [...]
    }
-4
ответ дан 4 December 2019 в 03:39
поделиться

мое решение, немного сложное, но оно мне понадобилось для тестовой среды :-) не бойтесь немецких javadocs, имена и тела методов должны быть достаточными для его получения

ПЕРВЫЙ создать аннотацию для обозначения класса или метода для работы с базой данных (создать таблицу и / или вставить операторы)


@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface SchemaImport {

    /**
     * Location der Schemadatei(en). Die Datei darf nur SQL Statements enthalten.
     * Wird keine Location gesetzt, greift der Defaultwert.
     * @return String
     */
    String[] locationsBefore() default {"input/schemas/before.sql"};

    /**
     * Location der Schemadatei(en). Die Datei darf nur SQL Statements enthalten.
     * Wird keine Location gesetzt, greift der Defaultwert.
     * @return String
     */
    String[] locationsAfter() default {"input/schemas/after.sql"};

    /**
     * Ein SchemaImport findet nur bei passender Umgebungsvariable statt, mit diesem
     * Flag kann dieses Verhalten geändert werden.
     * @return boolean
     */
    boolean override() default false;
}

ВТОРОЙ создать прослушиватель, который ищет аннотацию, AbstractTestExecutionListener - это класс Spring Framework из


        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>org.springframework.test</artifactId>
            <version>2.5.6</version>
        </dependency>


public class SchemaImportTestExecutionListener extends AbstractTestExecutionListener
        implements ApplicationContextAware {

    /**
     * Standard LOG Definition.
     */
    private static final Logger LOG = LoggerFactory.getLogger(
            SchemaImportTestExecutionListener.class);
    /**
     * Datasource Name - gemeint ist der Name der Datasource Bean bzw. die ID.
     */
    private static final String DATASOURCE_NAME = "dataSource";
    /**
     * JDBC Template.
     */
    private SimpleJdbcTemplate simpleJdbcTemplate;
    /**
     * Flag um festzustellen ob prepareTestInstance schon gerufen wurde.
     */
    private boolean isAlreadyPrepared = false;

    /**
     * Standard Constructor, laut API von konkreten Implementierungen für
     * TestexecutionListener erwartet, es geht aber auch ohne.
     */
    public SchemaImportTestExecutionListener() {
    }

    /**
     * Für jede Testklasse die mit der {@link SchemaImport} Annotation ausgezeichnet
     * ist, wird ein entsprechender SchemaImport durchgeführt.
     * 

* Der SchemaImport findet pro Klasse exakt einmal statt. Diese Verhalten * entspricht der BeforeClass * Annotation von JUnit. *

* Achtung mit Nutzung von Schemaimport auf Klassenebene ist kein * Rollback möglich, stattdessen SchemaImport auf Methodenebene nutzen. * * @param testContext * @throws java.lang.Exception */ @Override public void prepareTestInstance(TestContext testContext) throws Exception { final SchemaImport annotation = AnnotationUtils.findAnnotation(testContext.getTestClass(), SchemaImport.class); if ((annotation != null) && !isAlreadyPrepared && (isPropertyOrOverride(annotation))) { executeSchemaImports(testContext, annotation.locationsBefore(), true); isAlreadyPrepared = true; } } /** * Für jede Testmethode mit {@link SchemaImport} werden die angegebenen * Schema Dateien als SQL ausgeführt. * * @param testContext * @throws java.lang.Exception */ @Override public void beforeTestMethod(TestContext testContext) throws Exception { // nur für Methoden mit passender Annotation Schemaimport durchführen final SchemaImport annotation = AnnotationUtils.findAnnotation(testContext.getTestMethod(), SchemaImport.class); if (annotation != null) { executeSchemaImports(testContext, annotation.locationsBefore(), true); } } @Override public void afterTestMethod(TestContext testContext) throws Exception { // nur für Methoden mit passender Annotation Schemaimport durchführen final SchemaImport annotation = AnnotationUtils.findAnnotation(testContext.getTestMethod(), SchemaImport.class); if (annotation != null) { executeSchemaImports(testContext, annotation.locationsAfter(), false); } } /** * Prüfen ob passende Umgebungsvariable gesetzt wurde. Diese kann durch * entsprechendes Setzen des Flags an der Annotation überschrieben werden. * @return */ private boolean isPropertyOrOverride(SchemaImport annotation) { String prop = System.getProperty(TYPEnviroment.KEY_ENV); if (StringUtils.trimToEmpty(prop).equals(TYPEnviroment.EMBEDDED.getEnv())) { LOG.info("Running SchemaImport, Enviroment is set:'" + prop + "'"); return true; } else { if (annotation.override()) { LOG.warn( "Running SchemaImport, although Enviroment is set:'" + prop + "'"); return true; } else { LOG.warn( "Not Running SchemaImport cause neither Environment or SchemaImport.override are set."); return false; } } } /** * Hilfesmethode die eigentlichen SchemaImport kapselt. * * @param testContext * @param locations */ private void executeSchemaImports(TestContext testContext, String[] locations, boolean checkLocations) { // für jede Datei SchemaImport durchführen, korrekte Reihenfolge // ist durch Entwickler zu gewährleisten if (locations.length > 0) { for (String location : locations) { if (StringUtils.trimToNull(location) != null) { if (isResourceExistant(location, checkLocations)) { LOG.info("Executing Schema Location: '" + location + "'"); SimpleJdbcTestUtils.executeSqlScript(getJdbcTemplate( testContext), new ClassPathResource(location), false); } else { LOG.warn( "Schema Location '" + location + "' for SchemaImport not found."); } } else { throw new RuntimeException("SchemaImport with empty Locations in:'" + testContext.getTestClass().getSimpleName() + "'"); } } } } /** * * @param resource * @return */ private boolean isResourceExistant(String resource, boolean checkLocations) { try { new ClassPathResource(resource).getInputStream(); return true; } catch (IOException ex) { if (checkLocations) { throw new RuntimeException(ex); } else { return false; } } } /** * Hilfsmethode um an ein JdbcTemplate heranzukommen. * * @param TestContext * @return SimpleJdbcTemplate */ private SimpleJdbcTemplate getJdbcTemplate(TestContext context) { if (this.simpleJdbcTemplate == null) { this.simpleJdbcTemplate = new SimpleJdbcTemplate(getDataSource( context)); } return this.simpleJdbcTemplate; } /** * Hilfsmethode um an die Datasource heranzukommen. * * @param testContext * @return DataSource */ private DataSource getDataSource(TestContext testContext) { return (DataSource) testContext.getApplicationContext().getBean( DATASOURCE_NAME, DataSource.class); } /** {@inheritDoc} */ @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { throw new UnsupportedOperationException("Not supported yet."); } }

THIRD добавить слушателя к выполнению теста


@ContextConfiguration(locations = {"classpath*:spring/persistence/*.xml"})
@Transactional
@TestExecutionListeners({
    TransactionalTestExecutionListener.class,
    SchemaImportTestExecutionListener.class})
public abstract class AbstractAvHibernateTests extends AbstractAvTests {

    /**
     * SimpleJdbcTemplate für Subclasses verfügbar.
     */
    @Autowired
    protected SimpleJdbcTemplate simpleJdbcTemplate;
}

в использовании


@SchemaImport(locationsBefore={"schemas/spring-batch/2.0.0/schema-hsqldb.sql"})
public class FooTest extends AbstractAvHibernateTests {
}

важно отметить - остерегайтесь проблем с потоками при использовании параллельного тестирования testNg, для чтобы это работало, должны быть некоторые «синхронизированные» маркеры для методов getJdbcTemplate / dataSource в слушателе

ps:

код для базового класса теста:


@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath*:spring/*.xml"})
@TestExecutionListeners({
    DependencyInjectionTestExecutionListener.class,
    DirtiesContextTestExecutionListener.class,
    LogDurationTestExecutionListener.class,
    LogMethodNameTestExecutionListener.class})
public abstract class AbstractAvTests implements ApplicationContextAware {

    /**
     * Logger für Subclasses verfügbar.
     */
    protected final Logger LOG = LoggerFactory.getLogger(getClass());
    /**
     * {@link ApplicationContext} für Subclasses verfügbar.
     */
    protected ApplicationContext applicationContext;

    /** {@inheritDoc } */
    @Override
    public final void setApplicationContext(final ApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
    }
}

LogDurationTestExecutionListener и LogMethodNameTestExecutionListener - это пользовательские слушатели, не предоставляемые Spring, но не требуется для правильной работы schemaImport

6
ответ дан 4 December 2019 в 03:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: