java - 编写 JPA 存储库 JUnit,其中一个存储库依赖于其他存储库

标签 java spring unit-testing junit spring-data-jpa

考虑一个例子,我有两个实体如下

  1. 属性.java

    @Entity
         @Table(name = "attribute")
         public class Attribute {
            @Id
            @GeneratedValue(strategy=GenerationType.IDENTITY)
            @Getter private Long id;
    
    <pre><code>    @Column(name="name")
        @Getter private String name;    
    
        @Column(name = "source")
        @Getter private String source;
    
        protected Attribute(){}
        public Attribute(final String name, final String source) {
            this.name = name;
            this.source = source;
        }
    </code></pre>
    
    } 
  2. AttributeGroup.java

    @Entity
        @Table(name = "attribute_group")
        public class AttributeGroup {
    
    <pre><code>    @Id
        @GeneratedValue(strategy=GenerationType.IDENTITY)
        @Getter private Long id;
    
        @Column(name="name")
        @Getter private String name;
    
        @Column(name = "value")
        @Getter private String value;
    
        @Getter
        @Column(name="attribute_id", nullable=false)
        protected Long attributeId;
    
        @Getter
        @OneToOne(optional=true, fetch = FetchType.EAGER)
        @JoinColumn(name="attribute_id",  updatable=false, insertable=false,  referencedColumnName="id")
        private Attribute attribute;
    
        protected AttributeGroup(){}
    }
    </code></pre>
    
    

两个存储库

  1. AttributeRepository.java

    公共(public)接口(interface)AttributeRepository{}

  2. AttributeGroupRepository.java

    public interface AttributeGroupRepository {
    
    <pre><code>/**
     * find list of Groups by attribute name
     * @param attribute
     * @return
     */
    List<AttributeGroup> findByAttribute(Attribute attribute);
    </code></pre>
    
    }

AttributeGroupRepositoryTest.java

<pre><code>@RunWith(SpringRunner.class)
@DataJpaTest
@TestExecutionListeners({DependencyInjectionTestExecutionListener.class,
    TransactionalTestExecutionListener.class, DbUnitTestExecutionListener.class})
@DatabaseSetup(AttributeGroupRepositoryTest.DATASET)
@DatabaseTearDown(type = DatabaseOperation.CLEAN_INSERT, value = { AttributeGroupRepositoryTest.DATASET })
public class AttributeGroupRepositoryTest {
    protected static final String DATASET = "classpath:/attribute-group-test-data.xml";

    @Autowired
    private AttributeGroupRepository groupRepository;

    @Test
    public void findByAttributes(){
        Attribute attribute=new Attribute("Data","abc");
        List<AttributeGroup> groups = groupRepository.findByAttribute(attribute);

        assertThat(groups.isEmpty(), Matchers.is(false));
        assertThat(groups.size(), Matchers.equalTo(2));
        assertThat(groups.stream().findFirst().get().getId(), Matchers.equalTo(5L));
        assertThat(groups.stream().findFirst().get().getName(), Matchers.equalTo("GROUP1"));
        assertThat(groups.stream().findFirst().get().getValue(), Matchers.equalTo("HW"));
        assertThat(groups.stream().findFirst().get().getAttribute().getId(), Matchers.equalTo(3L));
        assertThat(groups.stream().findFirst().get().getAttribute().getName(), Matchers.equalTo("Data"));
        assertThat(groups.stream().findFirst().get().getAttribute().getSource(), Matchers.equalTo("abc"));
    }

}

xml文件

<?xml version="1.0" encoding="UTF-8"?>
<dataset>
   <lima_attribute id="1" name="Issuer Ultimate Parent Name" source="VENTURE"/>
   <lima_attribute id="2" name="Currency" source="abc"/>
   <lima_attribute id="3" name="Data" source="abc"/>
   <lima_attribute_group id="1" name="CurrencyGroup" value="AUS" attribute_id="2"/>
   <lima_attribute_group id="2" name="CurrencyGroup" value="GBP" attribute_id="2"/>
   <lima_attribute_group id="3" name="CurrencyGroup" value="BHD" attribute_id="2"/>
   <lima_attribute_group id="4" name="CurrencyGroup" value="AFA" attribute_id="2"/>
   <lima_attribute_group id="5" name="GROUP1" value="HW" attribute_id="3"/>
   <lima_attribute_group id="6" name="GROUP1" value="VOL" attribute_id="3"/>
</dataset>

上面的测试用例抛出异常

org.springframework.dao.InvalidDataAccessApiUsageException: org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: com.entity.attribute.Attribute; nested exception is java.lang.IllegalStateException: org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: com.entity.attribute.Attribute

    at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:381)
Caused by: java.lang.IllegalStateException: org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: com.entity.attribute.Attribute

由于此测试依赖于属性存储库,并且 Junit 是单元测试用例,因此我不想使用属性存储库。

还有其他方法可以模拟其他存储库数据吗?

最佳答案

我找到了无需使用其他存储库即可执行测试用例的方法。

替换下面的行:

List<AttributeGroup> groups = groupRepository.findByAttribute(attribute);

List<AttributeGroup> groups = groupRepository.findByAttributeNameAndAttributeSource("Data","abc");

关于java - 编写 JPA 存储库 JUnit,其中一个存储库依赖于其他存储库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48636905/

相关文章:

c# - Assert.AreEqual 与 Assert.IsTrue/Assert.IsFalse

java - 无返回声明问题

java - 启动时引导数据,Spring MVC,Hibernate

java - Eclipse 中的动态 Web 项目问题

java - Tomcat 7 最大线程问题

java - 如何从 Bean 定义中访问 Bean Id

java - 如何使用 JAVA Rest Assure 修复此错误

c# - MSUnit 测试异步 hell

java - 如何使用 JDK 11 为 Collection.toArray() 提供生成器函数?

java - 使用 values.xml 设置 Android Activity 屏幕方向