Spring `JpaRepository` 仅在测试范围内使用
Spring `JpaRepository` to be used only in test scope
我有一个JpaRepository
,看起来像
@Repository
public interface CustomRepository extends JpaRepository<EntityType, Integer> {
// Methods
}
可能会有长时间 运行 的查询,在这种情况下,我需要强制执行超时。我已经成功添加了与超时相关的配置(正在使用的连接池是Druid
,如果这很重要的话),现在我想在单元测试中测试它。我在 JpaRepository<T, ID>
界面中使用以下方法。
@Query(value = "SELECT benchmark(:count, MD5('3094803'))", nativeQuery = true)
void run(@Param("count") Long count);
此方法 运行 成功并演示了预期的行为。但是,鉴于此方法将 运行 随着参数 count
的值变大而变长,因此在生产代码中使用此方法只是为了测试超时,这让我很困扰,因为这可能最终成为一个可以被利用来发起拒绝攻击的漏洞。
所以对于这个问题,有没有什么方法可以在我的测试范围内使用这个确切的方法,而不用在生产代码中?
事实证明,事情并没有那么复杂。鉴于此项目 运行ning Spring,我可以在我的测试源中扩展上述存储库,如下所示。
package com.project.package.repo;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
@Repository
public interface TimedCustomRepository extends CustomRepository {
@Query(value = "SELECT benchmark(:count, MD5('3094803'))", nativeQuery = true)
void run(@Param("count") Long count);
}
因为我有 JUnit4,所以我可以进行测试 class,它将 运行 在 Spring 引导时,如下所示。
package om.project.package.repo;
import com.github.database.rider.spring.api.DBRider;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.orm.jpa.JpaSystemException;
import org.springframework.test.context.junit4.SpringRunner;
@SpringBootTest
@RunWith(SpringRunner.class)
@DBRider(dataSourceBeanName = "primaryDataSource") //Data source wiring; Not that important.
public class TransactionHistoryJpaRepoTest {
@Autowired //---(1)
private TimedCustomRepository timedCustomRepository;
@Test(expected = JpaSystemException.class)
public void whenQueryTimeoutOccurs() {
timedCustomRepository.run(100000000L);
}
}
(1)
处的 属性 将使用我们在上面创建的存储库 bean 进行连接,并且此测试将按预期执行。给定 bean TimedCustomRepository
extends CustomRepository
,数据源配置和所有内容都将相同。最重要的是,由于这种带有长运行ning查询的方法现在只在测试范围内,因此它不会对测试范围之外产生任何影响。
我有一个JpaRepository
,看起来像
@Repository
public interface CustomRepository extends JpaRepository<EntityType, Integer> {
// Methods
}
可能会有长时间 运行 的查询,在这种情况下,我需要强制执行超时。我已经成功添加了与超时相关的配置(正在使用的连接池是Druid
,如果这很重要的话),现在我想在单元测试中测试它。我在 JpaRepository<T, ID>
界面中使用以下方法。
@Query(value = "SELECT benchmark(:count, MD5('3094803'))", nativeQuery = true)
void run(@Param("count") Long count);
此方法 运行 成功并演示了预期的行为。但是,鉴于此方法将 运行 随着参数 count
的值变大而变长,因此在生产代码中使用此方法只是为了测试超时,这让我很困扰,因为这可能最终成为一个可以被利用来发起拒绝攻击的漏洞。
所以对于这个问题,有没有什么方法可以在我的测试范围内使用这个确切的方法,而不用在生产代码中?
事实证明,事情并没有那么复杂。鉴于此项目 运行ning Spring,我可以在我的测试源中扩展上述存储库,如下所示。
package com.project.package.repo;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
@Repository
public interface TimedCustomRepository extends CustomRepository {
@Query(value = "SELECT benchmark(:count, MD5('3094803'))", nativeQuery = true)
void run(@Param("count") Long count);
}
因为我有 JUnit4,所以我可以进行测试 class,它将 运行 在 Spring 引导时,如下所示。
package om.project.package.repo;
import com.github.database.rider.spring.api.DBRider;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.orm.jpa.JpaSystemException;
import org.springframework.test.context.junit4.SpringRunner;
@SpringBootTest
@RunWith(SpringRunner.class)
@DBRider(dataSourceBeanName = "primaryDataSource") //Data source wiring; Not that important.
public class TransactionHistoryJpaRepoTest {
@Autowired //---(1)
private TimedCustomRepository timedCustomRepository;
@Test(expected = JpaSystemException.class)
public void whenQueryTimeoutOccurs() {
timedCustomRepository.run(100000000L);
}
}
(1)
处的 属性 将使用我们在上面创建的存储库 bean 进行连接,并且此测试将按预期执行。给定 bean TimedCustomRepository
extends CustomRepository
,数据源配置和所有内容都将相同。最重要的是,由于这种带有长运行ning查询的方法现在只在测试范围内,因此它不会对测试范围之外产生任何影响。