带有 rollbackOnly=true 的事务(mybatis-cdi:org.mybatis.cdi.Transactional)注释不在 Weld / JUnit 5 测试中回滚事务

问题描述 投票:0回答:1

我希望此类

UserMapperTest.java
运行回滚事务的测试(在本例中是一个简单的插入,其中字段电子邮件是唯一的,但问题的核心是关于回滚):

import jakarta.inject.Inject;
import org.jboss.weld.junit5.WeldInitiator;
import org.jboss.weld.junit5.WeldJunit5Extension;
import org.jboss.weld.junit5.WeldSetup;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mybatis.cdi.Transactional;
import java.math.BigInteger;

@ExtendWith(WeldJunit5Extension.class)
@TestMethodOrder(MethodOrderer.MethodName.class)
@Transactional(rollbackOnly = true)
public class UserMapperTest {
    @WeldSetup
    WeldInitiator weldInitiator = WeldInitiator.of(WeldInitiator.createWeld().enableDiscovery());

    @Inject
    @TestSessionFactory
    public UserMapper userMapper;

    @Test
    public void t1_insert_user() throws Exception {
        User u = userMapper.selectUserFromId(BigInteger.ONE);
        u.setId(null);
        u.setEmail(u.getEmail() + "2");
        userMapper.insertUser(u);
        Assertions.assertNotNull(u);
        Assertions.assertNotNull(u.getId());
    }
}

对于此测试有用的主要

pom.xml
依赖项是:

<!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-api -->
<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter</artifactId>
    <version>${junit.version}</version>
    <scope>test</scope>
</dependency>

<!-- https://mvnrepository.com/artifact/org.jboss.weld/weld-junit5 -->
<dependency>
    <groupId>org.jboss.weld</groupId>
    <artifactId>weld-junit5</artifactId>
    <version>${weld.junit5.version}</version>
    <scope>test</scope>
</dependency>

<!-- https://mvnrepository.com/artifact/org.jboss.weld.se/weld-se-core -->
<dependency>
    <groupId>org.jboss.weld.se</groupId>
    <artifactId>weld-se-core</artifactId>
    <version>${weld-se.version}</version>
    <scope>test</scope>
</dependency>

<!-- https://mvnrepository.com/artifact/jakarta.platform/jakarta.jakartaee-api -->
<dependency>
    <groupId>jakarta.platform</groupId>
    <artifactId>jakarta.jakartaee-api</artifactId>
    <version>${jakartaee-api.version}</version>
    <scope>provided</scope>
</dependency>

有了这些

versions

<junit.version>5.11.0-M2</junit.version>
<weld.junit5.version>4.0.3.Final</weld.junit5.version>
<weld-se.version>6.0.0.Beta4</weld-se.version>
<jakartaee-api.version>11.0.0-M4</jakartaee-api.version>

我的

bean.xml
是这样的:

<?xml version="1.0"?>
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
       bean-discovery-mode="all">
   <interceptors>
      <class>org.mybatis.cdi.LocalTransactionInterceptor</class>
   </interceptors>
</beans>

这是

TestSessionFactory
注释:

import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import jakarta.inject.Qualifier;

@Qualifier
@Retention(RUNTIME)
@Target({ TYPE, METHOD, FIELD, PARAMETER })
public @interface TestSessionFactory {
}

这是

SqlSessionFactoryProvider
的SqlSessionFactoryProviderTest测试实现:

import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.inject.Produces;

import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.cdi.SessionFactoryProvider;

public class SqlSessionFactoryProviderTest implements SqlSessionFactoryProvider {
    @Override
    @TestSessionFactory
    @Produces
    @ApplicationScoped
    @SessionFactoryProvider
    public SqlSessionFactory produceFactory() {
        return ConnectionFactory.getSqlSessionFactory();
    }
}

我曾经在 javax 和 junit 4 中使用类似的代码并且工作得很好。我正在尝试升级到 jakarta 和 junit 5。我可能缺少 WeldInitiator 上的某些内容。

userMapper
已正确注入,查询也正确运行,只是事务未回滚。

transactions junit5 mybatis rollback jboss-weld
1个回答
0
投票

在 Weld 的 JUnit 5 扩展中,测试类不是 CDI bean,因此

@Transactional
或应用于测试类的任何其他拦截器将不起作用。这是因为在创建扩展时,由于 JUnit API,这是不可能的。有一些 Weld-JUnit GH 问题对此进行了详细说明,例如 this one

JUnit 此后添加了许多 API,其中包括一个提供测试实例的 API,但这一更改将破坏至少一些使用

WeldInitiator
的现有测试的兼容性,因为提供实例对测试本身设置了一些期望。话虽这么说,我并不反对实施这一点;我只是缺乏时间。

作为您的场景的解决方法,您必须将拦截的方法登录移动到另一个可以照常拦截的测试 bean 中。

© www.soinside.com 2019 - 2024. All rights reserved.