【问题标题】:Writing JPA repository JUnit where one repository is dependent on Other编写 JPA 存储库 JUnit,其中一个存储库依赖于其他存储库
【发布时间】:2018-02-06 06:39:32
【问题描述】:

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

  1. 属性.java

    @Entity
         @Table(name = "attribute")
         public class Attribute {
            @Id
            @GeneratedValue(strategy=GenerationType.IDENTITY)
            @Getter private Long id;
    
    
        @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;
        }
    
    }
  2. AttributeGroup.java

    @Entity
        @Table(name = "attribute_group")
        public class AttributeGroup {
    
    
        @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(){}
    }
    

两个仓库

  1. AttributeRepository.java

    public interface AttributeRepository{}

  2. AttributeGroupRepository.java

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

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 是单元测试用例,我不想使用属性存储库。

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

【问题讨论】:

  • 问题似乎是您创建并传递给 find 方法的 Attribute 对象。你能重写 findByAttributeName 的方法,只传递名称,看看会发生什么?

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


【解决方案1】:

我找到了在不使用其他存储库的情况下执行测试用例的方法。

替换以下行:

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

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

【讨论】:

    【解决方案2】:

    您正在搜索一个没有持久化在repository中的对象,请先从AttributeRepository中找到该属性,然后在属性组repository中搜索返回的属性!

    Attribute attribute=attributeRepository.findByNameAndSource("Data",Source);
    if(attribute!=null){
       List<AttributeGroup> groups = groupRepository.findByAttribute(attribute);
    }
    

    【讨论】:

    • 就像Junit 一样,不依赖于其他类,所以实际上我不想在这里使用attributerepository。您可以建议我模拟数据的任何其他方式。
    猜你喜欢
    • 1970-01-01
    • 2014-12-03
    • 2010-11-23
    • 1970-01-01
    • 2023-03-27
    • 2011-05-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多