当前位置: 首页 > 知识库问答 >
问题:

jUnit测试中的Spring data-jpa bean验证

元修然
2023-03-14

在我最近的工作中,我使用SpringDataJPA来利用提供的存储库。当涉及到集成测试时,我无法配置(我假设)用于测试的spring上下文,结果bean验证在我的测试中不起作用。

我知道我可以注入验证器和单元测试我的注释,但事实并非如此。我正在编写集成测试,并希望测试数据库支持的存储库。

我准备了一个简单的项目来显示所有必要的项目文件。

当我运行测试时,有2个测试失败,我不知道为什么,hibernate验证器出现在类路径上。

Failed tests:   insertWrongEmail(com.example.core.data.jpa.UserRepositoryTest): Expected ConstraintViolationException wasn't thrown.
insertToShortPassword(com.example.core.data.jpa.UserRepositoryTest): Expected ConstraintViolationException wasn't thrown.
Apr 23, 2013 5:00:08 PM org.hibernate.validator.internal.util.Version <clinit>
INFO: HV000001: Hibernate Validator 4.3.1.Final

下面是源代码和mvn测试输出。

提前感谢您的帮助。

Java类(我去掉了注释、geter、seter、equals、hashCode、toString等):

基本实体

package com.example.core.data.jpa;

import javax.persistence.*;

@MappedSuperclass
public abstract class BaseEntity {
    public static final String SEQUENCE = "global_seq";

    @Id
    @SequenceGenerator(name = SEQUENCE, sequenceName = SEQUENCE)
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = SEQUENCE)
    @Column(name = "id")
    private Long id;

    public Long getId() {
        return id;
    }
}

使用者

package com.example.core.data.jpa;

import javax.persistence.*;
import javax.validation.constraints.Pattern;
import java.io.Serializable;
import java.util.List;

@Entity
@Table(name = "users")
@NamedQuery(name = "User.findByEmail", query = "select u from User u where upper(u.email) = :email")
public class User extends BaseEntity implements Serializable {
    private static final long serialVersionUID = 333700989750828624L;

    private static final int MAX_NAME_LENGTH = 128;
    private static final int MAX_EMAIL_LENGTH = 128;
    private static final int MAX_PASSWORD_LENGTH = 256;
    private static final int MIN_NAME_LENGTH = 6;

    private static final int EQUALS_MAGIC = 71;

    @Size(min = MIN_NAME_LENGTH)    
    @Column(name = "name", nullable = false, length = MAX_NAME_LENGTH)
    private String name;

    @Pattern(regexp = "^([0-9a-zA-Z]([-.\\w]*[0-9a-zA-Z])*@([0-9a-zA-Z][-\\w]*[0-9a-zA-Z]\\.)+[a-zA-Z]{2,9})$")
    @Column(name = "email", nullable = false, unique = true, length = MAX_EMAIL_LENGTH)
    private String email;

    @Column(name = "password", nullable = false, length = MAX_PASSWORD_LENGTH)
    private String password;

    @OneToMany(mappedBy="user", cascade={CascadeType.ALL}, fetch = FetchType.EAGER)
    private List<Role> roles;
//geters, seters, equals, hashCode
}

角色

package com.example.core.data.jpa;

import javax.persistence.*;
import java.io.Serializable;

@Entity
@Table(name = "roles")
public class Role extends BaseEntity implements Serializable {
    private static final long serialVersionUID = -2575871700366265974L;

    private static final int MAX_NAME_LENGTH = 128;

    @Column(name = "name", nullable = false, unique = true, length = MAX_NAME_LENGTH)
    private String name;

    @ManyToOne(cascade={CascadeType.ALL})
    private User user;
//geters, seters, equals, hashCode
}

用户存储测试

package com.example.core.data.jpa;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;
import com.example.core.data.repository.UserRepository;

import javax.inject.Inject;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;

import static org.junit.Assert.*;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:test-context.xml")
@Transactional
public class UserRepositoryTest {
    @Inject
    private UserRepository userRepository;

    private User user;

    private static final String NAME = "User Name";
    private static final String EMAIL = "user_name@example.com";
    private static final String PASSWORD = "PASSWORD";

    @Before
    public void setUp() {
        user = new User(NAME, EMAIL, PASSWORD);
    }

    @Test
    public void insert() {
        //given

        //when
        User inserted = userRepository.save(user);

        //then
        assertEquals(NAME, inserted.getName());
        assertEquals(EMAIL, inserted.getEmail());
        assertEquals(PASSWORD, inserted.getPassword());
        assertNotNull(inserted.getId());
    }

    @Test
    public void insertWrongEmail() {
        //given
        user.setEmail("NOT_AN_EMAIL_ADDRESS");

        //when
        try {
            userRepository.save(user);

            fail("Expected ConstraintViolationException wasn't thrown.");

        } catch (ConstraintViolationException e) {
            //then

            assertEquals(1, e.getConstraintViolations().size());
            ConstraintViolation<?> violation =
                    e.getConstraintViolations().iterator().next();

            assertEquals("email", violation.getPropertyPath().toString());
            assertEquals(Pattern.class,
                    violation.getConstraintDescriptor()
                            .getAnnotation().annotationType());
        }
    }

    @Test
    public void insertToShortName() {
        //given
        user.setName("SHORT");

        //when
        try {
            userRepository.save(user);

            fail("Expected ConstraintViolationException wasn't thrown.");

        } catch (ConstraintViolationException e) {
        //then

            assertEquals(1, e.getConstraintViolations().size());
            ConstraintViolation<?> violation =
                    e.getConstraintViolations().iterator().next();

            assertEquals("name", violation.getPropertyPath().toString());
            assertEquals(Size.class,
                    violation.getConstraintDescriptor()
                            .getAnnotation().annotationType());
        }
    }
}

用户库

package com.example.core.data.repository;

import org.springframework.data.repository.PagingAndSortingRepository;
import com.example.core.data.jpa.User;

public interface UserRepository extends PagingAndSortingRepository<User, Long> {
}

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>
    <artifactId>data-jpa</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>
    <name>Exampl core jpa package</name>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.hibernate.javax.persistence</groupId>
            <artifactId>hibernate-jpa-2.0-api</artifactId>
            <version>1.0.1.Final</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate.java-persistence</groupId>
            <artifactId>jpa-api</artifactId>
            <version>2.0-cr-1</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>4.2.0.Final</version>
        </dependency>
        <dependency>
            <groupId>javax.validation</groupId>
            <artifactId>validation-api</artifactId>
            <version>1.0.0.GA</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>4.3.1.Final</version>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-jdk14</artifactId>
            <version>1.6.0</version>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.codehaus.jackson</groupId>
            <artifactId>jackson-mapper-asl</artifactId>
            <version>1.9.12</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax.inject</groupId>
            <artifactId>javax.inject</artifactId>
            <version>1</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-jpa</artifactId>
            <version>1.2.0.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>cglib</groupId>
            <artifactId>cglib</artifactId>
            <version>2.2.2</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>3.2.2.RELEASE</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.hsqldb</groupId>
            <artifactId>hsqldb</artifactId>
            <version>2.2.9</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

测试上下文。xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:jpa="http://www.springframework.org/schema/data/jpa"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:jdbc="http://www.springframework.org/schema/jdbc"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/data/jpa
            http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
        http://www.springframework.org/schema/jdbc
            http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd
        http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/tx
            http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">

    <context:annotation-config/>
    <jpa:repositories base-package="com.example.core.data.repository" />
    <tx:annotation-driven transaction-manager="transactionManager" />

    <jdbc:embedded-database id="dataSource" type="HSQL"/>

    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"
            p:entityManagerFactory-ref="entityManagerFactory" />

    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
          p:dataSource-ref="dataSource" p:jpaVendorAdapter-ref="jpaAdapter" >
        <property name="loadTimeWeaver">
            <bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver" />
        </property>
        <property name="packagesToScan">
            <list>
                <value>com.example.core.data.jpa</value>
            </list>
        </property>
    </bean>

    <bean id="jpaAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"
          p:generateDdl="true" p:database="HSQL" />

    <bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"
            p:messageInterpolator-ref="messageInterpolator" p:validationMessageSource-ref="messageSource" />

    <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource"
          p:basename="classpath:I18N/messages,classpath:ValidationMessages*.properties" />

    <bean id="messageInterpolator"
          class="org.hibernate.validator.messageinterpolation.ResourceBundleMessageInterpolator" />
</beans>

MVN测试输出

[INFO] Scanning for projects...
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building Example core jpa package 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] 
[INFO] --- maven-resources-plugin:2.5:resources (default-resources) @ data-jpa ---
[debug] execute contextualize
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 1 resource
[INFO] 
[INFO] --- maven-compiler-plugin:2.3.2:compile (default-compile) @ data-jpa ---
[INFO] Nothing to compile - all classes are up to date
[INFO] 
[INFO] --- maven-resources-plugin:2.5:testResources (default-testResources) @ data-jpa ---
[debug] execute contextualize
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 1 resource
[INFO] 
[INFO] --- maven-compiler-plugin:2.3.2:testCompile (default-testCompile) @ data-jpa ---
[INFO] Nothing to compile - all classes are up to date
[INFO] 
[INFO] --- maven-surefire-plugin:2.10:test (default-test) @ data-jpa ---
[INFO] Surefire report directory: /home/[..]/data-jpa/target/surefire-reports

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running com.example.core.data.jpa.UserRepositoryTest
Apr 23, 2013 4:39:34 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [test-context.xml]
Apr 23, 2013 4:39:35 PM org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.GenericApplicationContext@3cd6ad74: startup date [Tue Apr 23 16:39:35 CEST 2013]; root of context hierarchy
Apr 23, 2013 4:39:35 PM org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor <init>
INFO: JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
Apr 23, 2013 4:39:35 PM org.springframework.context.support.AbstractApplicationContext$BeanPostProcessorChecker postProcessAfterInitialization
INFO: Bean 'org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver#423dc560' of type [class org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
Apr 23, 2013 4:39:35 PM org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseFactory initDatabase
INFO: Creating embedded database 'dataSource'
Apr 23, 2013 4:39:35 PM org.springframework.context.support.AbstractApplicationContext$BeanPostProcessorChecker postProcessAfterInitialization
INFO: Bean 'dataSource' of type [class org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseFactoryBean] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
Apr 23, 2013 4:39:35 PM org.springframework.context.support.AbstractApplicationContext$BeanPostProcessorChecker postProcessAfterInitialization
INFO: Bean 'dataSource' of type [class org.springframework.jdbc.datasource.SimpleDriverDataSource] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
Apr 23, 2013 4:39:35 PM org.springframework.context.support.AbstractApplicationContext$BeanPostProcessorChecker postProcessAfterInitialization
INFO: Bean 'jpaAdapter' of type [class org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
Apr 23, 2013 4:39:35 PM org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean createNativeEntityManagerFactory
INFO: Building JPA container EntityManagerFactory for persistence unit 'default'
Apr 23, 2013 4:39:35 PM org.hibernate.annotations.common.Version <clinit>
INFO: HCANN000001: Hibernate Commons Annotations {4.0.1.Final}
Apr 23, 2013 4:39:35 PM org.hibernate.Version logVersion
INFO: HHH000412: Hibernate Core {4.2.0.Final}
Apr 23, 2013 4:39:35 PM org.hibernate.cfg.Environment <clinit>
INFO: HHH000206: hibernate.properties not found
Apr 23, 2013 4:39:35 PM org.hibernate.cfg.Environment buildBytecodeProvider
INFO: HHH000021: Bytecode provider name : javassist
Apr 23, 2013 4:39:35 PM org.hibernate.ejb.Ejb3Configuration configure
INFO: HHH000204: Processing PersistenceUnitInfo [
    name: default
    ...]
Apr 23, 2013 4:39:36 PM org.hibernate.service.jdbc.connections.internal.ConnectionProviderInitiator instantiateExplicitConnectionProvider
INFO: HHH000130: Instantiating explicit connection provider: org.hibernate.ejb.connection.InjectedDataSourceConnectionProvider
Apr 23, 2013 4:39:36 PM org.hibernate.dialect.Dialect <init>
INFO: HHH000400: Using dialect: org.hibernate.dialect.HSQLDialect
Apr 23, 2013 4:39:36 PM org.hibernate.engine.transaction.internal.TransactionFactoryInitiator initiateService
INFO: HHH000268: Transaction strategy: org.hibernate.engine.transaction.internal.jdbc.JdbcTransactionFactory
Apr 23, 2013 4:39:36 PM org.hibernate.hql.internal.ast.ASTQueryTranslatorFactory <init>
INFO: HHH000397: Using ASTQueryTranslatorFactory
Apr 23, 2013 4:39:36 PM org.hibernate.validator.internal.util.Version <clinit>
INFO: HV000001: Hibernate Validator 4.3.1.Final
Apr 23, 2013 4:39:37 PM org.hibernate.tool.hbm2ddl.SchemaUpdate execute
INFO: HHH000228: Running hbm2ddl schema update
Apr 23, 2013 4:39:37 PM org.hibernate.tool.hbm2ddl.SchemaUpdate execute
INFO: HHH000102: Fetching database metadata
Apr 23, 2013 4:39:37 PM org.hibernate.tool.hbm2ddl.SchemaUpdate execute
INFO: HHH000396: Updating schema
Apr 23, 2013 4:39:37 PM org.hibernate.tool.hbm2ddl.DatabaseMetadata getTableMetadata
INFO: HHH000262: Table not found: roles
Apr 23, 2013 4:39:37 PM org.hibernate.tool.hbm2ddl.DatabaseMetadata getTableMetadata
INFO: HHH000262: Table not found: users
Apr 23, 2013 4:39:37 PM org.hibernate.tool.hbm2ddl.DatabaseMetadata getTableMetadata
INFO: HHH000262: Table not found: roles
Apr 23, 2013 4:39:37 PM org.hibernate.tool.hbm2ddl.DatabaseMetadata getTableMetadata
INFO: HHH000262: Table not found: users
Apr 23, 2013 4:39:37 PM org.hibernate.tool.hbm2ddl.DatabaseMetadata getTableMetadata
INFO: HHH000262: Table not found: global_seq
Apr 23, 2013 4:39:37 PM org.hibernate.tool.hbm2ddl.SchemaUpdate execute
INFO: HHH000232: Schema update complete
Apr 23, 2013 4:39:37 PM org.springframework.context.support.AbstractApplicationContext$BeanPostProcessorChecker postProcessAfterInitialization
INFO: Bean 'entityManagerFactory' of type [class org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
Apr 23, 2013 4:39:37 PM org.springframework.context.support.AbstractApplicationContext$BeanPostProcessorChecker postProcessAfterInitialization
INFO: Bean 'org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#0' of type [class org.springframework.transaction.annotation.AnnotationTransactionAttributeSource] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
Apr 23, 2013 4:39:37 PM org.springframework.context.support.AbstractApplicationContext$BeanPostProcessorChecker postProcessAfterInitialization
INFO: Bean 'org.springframework.transaction.config.internalTransactionAdvisor' of type [class org.springframework.transaction.interceptor.BeanFactoryTransactionAttributeSourceAdvisor] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
Apr 23, 2013 4:39:37 PM org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@69950b4: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.annotation.internalPersistenceAnnotationProcessor,userRepository,org.springframework.data.repository.core.support.RepositoryInterfaceAwareBeanPostProcessor#0,org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor#0,org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor#0,org.springframework.aop.config.internalAutoProxyCreator,org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#0,org.springframework.transaction.interceptor.TransactionInterceptor#0,org.springframework.transaction.config.internalTransactionAdvisor,dataSource,transactionManager,entityManagerFactory,jpaAdapter,validator,messageSource,messageInterpolator,org.springframework.context.annotation.ConfigurationClassPostProcessor$ImportAwareBeanPostProcessor#0]; root of factory hierarchy
Apr 23, 2013 4:39:38 PM org.springframework.test.context.transaction.TransactionalTestExecutionListener startNewTransaction
INFO: Began transaction (1): transaction manager [org.springframework.orm.jpa.JpaTransactionManager@58eac93b]; rollback [true]
Apr 23, 2013 4:39:38 PM org.springframework.test.context.transaction.TransactionalTestExecutionListener endTransaction
INFO: Rolled back transaction after test execution for test context [TestContext@2b98919b testClass = UserRepositoryTest, testInstance = com.example.core.data.jpa.UserRepositoryTest@2d7f6d79, testMethod = insert@UserRepositoryTest, testException = [null], mergedContextConfiguration = [MergedContextConfiguration@8ec3a45 testClass = UserRepositoryTest, locations = '{classpath:test-context.xml}', classes = '{}', contextInitializerClasses = '[]', activeProfiles = '{}', contextLoader = 'org.springframework.test.context.support.DelegatingSmartContextLoader', parent = [null]]]
Apr 23, 2013 4:39:38 PM org.springframework.test.context.transaction.TransactionalTestExecutionListener startNewTransaction
INFO: Began transaction (2): transaction manager [org.springframework.orm.jpa.JpaTransactionManager@58eac93b]; rollback [true]
Apr 23, 2013 4:39:38 PM org.springframework.test.context.transaction.TransactionalTestExecutionListener endTransaction
INFO: Rolled back transaction after test execution for test context [TestContext@2b98919b testClass = UserRepositoryTest, testInstance = com.example.core.data.jpa.UserRepositoryTest@1fcf7061, testMethod = insertWrongEmail@UserRepositoryTest, testException = java.lang.AssertionError: Expected ConstraintViolationException wasn't thrown., mergedContextConfiguration = [MergedContextConfiguration@8ec3a45 testClass = UserRepositoryTest, locations = '{classpath:test-context.xml}', classes = '{}', contextInitializerClasses = '[]', activeProfiles = '{}', contextLoader = 'org.springframework.test.context.support.DelegatingSmartContextLoader', parent = [null]]]
Apr 23, 2013 4:39:38 PM org.springframework.test.context.transaction.TransactionalTestExecutionListener startNewTransaction
INFO: Began transaction (3): transaction manager [org.springframework.orm.jpa.JpaTransactionManager@58eac93b]; rollback [true]
Apr 23, 2013 4:39:38 PM org.springframework.test.context.transaction.TransactionalTestExecutionListener endTransaction
INFO: Rolled back transaction after test execution for test context [TestContext@2b98919b testClass = UserRepositoryTest, testInstance = com.example.core.data.jpa.UserRepositoryTest@168ee2a9, testMethod = insertToShortPassword@UserRepositoryTest, testException = java.lang.AssertionError: Expected ConstraintViolationException wasn't thrown., mergedContextConfiguration = [MergedContextConfiguration@8ec3a45 testClass = UserRepositoryTest, locations = '{classpath:test-context.xml}', classes = '{}', contextInitializerClasses = '[]', activeProfiles = '{}', contextLoader = 'org.springframework.test.context.support.DelegatingSmartContextLoader', parent = [null]]]
Tests run: 3, Failures: 2, Errors: 0, Skipped: 0, Time elapsed: 3.712 sec <<< FAILURE!

Results :

Failed tests:   insertWrongEmail(com.example.core.data.jpa.UserRepositoryTest): Expected ConstraintViolationException wasn't thrown.
  insertToShortPassword(com.example.core.data.jpa.UserRepositoryTest): Expected ConstraintViolationException wasn't thrown.

Tests run: 3, Failures: 2, Errors: 0, Skipped: 0

[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 6.216s
[INFO] Finished at: Tue Apr 23 16:39:38 CEST 2013
[INFO] Final Memory: 7M/245M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.10:test (default-test) on project data-jpa: There are test failures.
[ERROR] 
[ERROR] Please refer to /home/[..]/data-jpa/target/surefire-reports for the individual test results.
[ERROR] -> [Help 1]
[ERROR] 
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR] 
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoFailureException

Process finished with exit code 1

解决了的

在@gunnar给出答案后,我进行了更改测试,以在存储库之后刷新持久性上下文。保存并按预期工作。

对用户存储库的更改

//inject entity manager
@PersistenceContext
private EntityManager entityManager;

//add flush after save in test method
@Test
public void insertWrongEmail() {
    //given
    user.setEmail("NOT_AN_EMAIL_ADDRESS");

    //when
    try {
        userRepository.save(user);
        entityManager.flush();

        fail("Expected ConstraintViolationException wasn't thrown.");

根据@andyb的推荐,我已经切换到eclipselink,测试工作不需要冲洗。这是我将采用的解决方案,我认为切换实现比使用变通方法更好。

共有2个答案

戚良弼
2023-03-14

执行存储库操作后刷新持久性上下文可能会起作用。JPA仅在与数据库同步时,即在提交或刷新期间调用Bean验证。

葛炜
2023-03-14

我设法在本地重现了问题中描述的问题,尽管在添加回丢失的get/set函数和UserRepository类之后:-)

经过一番挖掘,我发现了两个存在的问题:JPA ConstraintViolation与Rollback和Hibernate在与Bean验证API结合时是否不遵循JPA规范?

两者似乎都认为Hibernate没有正确抛出ConstraintValidationException

第二个问题的结果是HHH-8028-entityManager存在缺陷。坚持不抛出针对Hibernate引发的ConstraintValidationException。

为了确认这是同一个问题,我切换到一个简单的@GeneratedValueinsertErrorEmailInsertToSortPassword仍然失败,但我认为密码字段缺少@Size(min=6)。加上这些之后,所有测试都通过了。

返回到您配置的@GeneratedValue,然后我将Hibernate替换为Eclipse Link持久性框架。两项测试都通过了,这似乎证实了之前问题中的发现。我所做的改变是:

波姆。xml更改添加了Eclipse站点上描述的jpa工件

<dependency>
   <groupId>org.eclipse.persistence</groupId>
   <artifactId>org.eclipse.persistence.jpa</artifactId>
   <version>2.4.0</version>
   <scope>compile</scope>
</dependency>

切换到EclipseLinekjpavendorAdapter

<bean id="jpaAdapter" class="org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter"
    p:generateDdl="true" p:database="HSQL" />

添加日食。编织属性,如EclipseLkJPavendorAdapter而非HibernateJpaVendorAdapter问题所述

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
    p:dataSource-ref="dataSource" p:jpaVendorAdapter-ref="jpaAdapter" >
    <!-- existing configuration is identical -->
    <property name="jpaPropertyMap">
      <map>
        <entry key="eclipselink.weaving" value="false"/>
      </map>
    </property>
</bean>

User.java变化

我需要添加一个默认的无参数构造函数。您可能已经有一个完整的用户。java类。

 类似资料:
  • 问题内容: 在最近的工作中,我使用spring-data- jpa来利用提供的存储库。在进行集成测试时,我无法配置(我假设)用于测试的Spring上下文,因此结果Bean验证在我的测试中不起作用。 我知道我可以注入验证器,并对注释进行单元测试,但事实并非如此。我正在编写集成测试,并且想测试具有数据库支持的存储库。 我准备了一个简单的项目来显示所有必要的项目文件。 当我运行测试时,2失败了,我也不知

  • 是否有一种方法可以在@RequestParams上进行spring控制器单元测试以进行javax验证。 我在控制器中有一个get方法,它用@size验证请求参数的大小。 有没有办法模拟jUnit测试大小验证器?我想验证大小为 样本测试: @RunWith(MockitoJUnitRunner.class)公共类MyControllerTest{ } 我也试过SpringRunner,但似乎还是失败

  • 我需要测试验证注释,但看起来它们不起作用。我不确定JUnit是否也是正确的。目前,测试将通过,但您可以看到指定的电子邮件地址是错误的。 JUnit 待测试类别

  • 与许多Java应用程序一样,我们在应用程序中使用Freemarker来呈现电子邮件。我们发现我们的一些模板并没有像我们想象的那样呈现,因此我们意识到我们应该为模板呈现编写一些单元测试。我设置了测试,并立即收到一个FileNotFoundException:找不到模板“my/Template.ftl”。 我想这一定是一个既能解决问题又能轻松解决的问题。那是很多小时前的事了,我意识到我错了;据我所知,

  • 在使用JUnit进行测试时,我无法理解一些事情,我编写了一些测试,而有些测试似乎可以简单地使用 而且 有些似乎不能与它们一起工作,所以我必须使用 而且 我理解@mockbean是在处理spring容器时使用的,而@mock只是用来复制/模拟某个类及其方法。但是什么时候才是使用@mockbean的最佳时机呢? 上面是我在spring boot应用程序中为一个控制器编写的测试,但当我使用@mock模拟

  • 我正在为Junit编写测试,以测试我编写的删除函数: 此方法适用于同时具有前后节点的双链接列表。 问题是:我们的大学将针对我们编写的测试运行错误代码,以确定我们是否编写了足够的测试来捕获错误代码和异常。 我知道他们将运行的两个测试,但不知道错误的含义。 > 失败:缺少逻辑 故障:缺少NextNodeRepairLogic 这是我没有考虑的两个测试,因为我无法理解这些错误的含义。有人知道这些错误可能