标签: spring-boot-test

SpringBoot 2 + Junit5:带有@Value的null

我有一个带有 SpringBoot2 和 Junit5 的应用程序,现在我正在尝试进行测试。我有一个名为 OrderService 的类,如下所示:

@Component
public class OrderService {
@Value("#{'${food.requires.box}'.split(',')}")
private List<String> foodRequiresBox;

@Value("#{'${properties.prioritization}'.split(',')}")
private List<String> prioritizationProperties;

@Value("${further.distance}")
private Integer slotMeterRange;

@Value("${slot.meters.long}")
private Double slotMetersLong;
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,该类有许多 @Value 注释,用于从 application.properties 文件中提取值。

在 POM 文件中,我有以下依赖项:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.0.1.RELEASE</version>
</parent>
<dependencies>
<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-engine</artifactId>
    <version>5.1.0</version>
</dependency>
<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-api</artifactId>
    <version>RELEASE</version>
</dependency>
<dependency>
    <groupId>org.junit.platform</groupId>
    <artifactId>junit-platform-launcher</artifactId>
    <version>1.1.0</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
    <version>2.0.5.RELEASE</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)

test/resources文件夹中,我有包含以下信息的 application.properties 文件:

properties.prioritization:vip,food
food.requires.box:pizza,cake,flamingo
further.distance:2
slot.meters.long:0.5
Run Code Online (Sandbox Code Playgroud)

测试文件如下所示:

properties.prioritization:vip,food
food.requires.box:pizza,cake,flamingo
further.distance:2
slot.meters.long:0.5
Run Code Online (Sandbox Code Playgroud)

但测试在尝试使用foodRequiresBox时会抛出 …

junit spring-boot junit5 spring-boot-test

4
推荐指数
1
解决办法
8632
查看次数

Spring Boot:如何覆盖单元测试中的默认属性

我尝试为单元测试加载第二个属性文件,这会覆盖一些属性。

@PropertySource用a加载它@Configuration不起作用,用 a 加载它@TestPropertySource也不起作用。仅properties直接设置@TesPropertySource有效,但当我尝试将其变成元注释时它不起作用。

这是一个示例项目:https ://github.com/cptwunderlich/SpringTestProperties

我更喜欢加载一个文件来影响所有测试(例如 with @PropertySource),但如果这不起作用,至少有一个自定义元注释会很好,所以我不必将其放在每个测试上测试。基本上我不想一些数据导入到数据库中进行测试(spring.datasource.data),然后还更改使用的数据库 - 无需复制整个配置并且每次都必须在两个位置更改它。

重要的部分:

@RunWith(SpringRunner.class)
@SpringBootTest
@TestPropertySource(locations = "classpath:application-test.properties")
public class TestconfigApplicationTests {

    @Value("${my.test.property}")
    private String testproperty;

    @Test
    public void assertValue() {
        Assert.assertEquals("foobar", testproperty);
    }

}
Run Code Online (Sandbox Code Playgroud)

或者测试包中的配置类:

@Configuration
@Order(Ordered.HIGHEST_PRECEDENCE)
@PropertySource("classpath:application-test.properties")
public class GlobalTestConfig {
}
Run Code Online (Sandbox Code Playgroud)

更新:

答案中的主要建议是使用@ActiveProfile激活“测​​试”配置文件,这将导致加载“application-test.yaml”。这比 更好@TestPropertySource,但我仍然需要在每个测试类上添加注释。我尝试创建一个元注释 - 它应该可以工作- 所以至少我只有一个自定义注释,我可以在其中捆绑其他设置。但这是行不通的。

完美的解决方案是使用一个配置类全局设置这些设置,而不必在每个测试上添加注释。我仍在寻找该解决方案,或者至少在关闭此问题之前调试元注释。编辑:我创建了一个 Jira 问题:SPR-17531

编辑

好吧,我有点困惑,所以我重新测试了所有不同的组合:

  • @TestPropertySource(locations = "classpath:application-test.properties") …

java spring unit-testing spring-boot spring-boot-test

4
推荐指数
1
解决办法
8383
查看次数

Spring Boot中mockito测试中的if...else语句问题

如何为 if...else 语句编写一个模拟测试用例,其中还包括异常测试,我对此很困惑。UserService 是一个接口

用户工厂.java

public class UserFactory {
    @Autowired
    private List<UserService> UserList;

    private final Map<String, UserService> UserMap = new HashMap<>();

    @PostConstruct
    public void initUserMap() {
        for (final UserService user : UserList) {
            UserMap.put(user.getUserId(), user);
        }
    }

    public UserService getUser(String userId) {
        final UserService userService = UserMap.get(userlId);
        if (null == userService) {
            throw new IllegalArgumentException("user are not in the group");
        }
        return userService;
    }
}
Run Code Online (Sandbox Code Playgroud)

用户服务(接口)

public interface UserService{
  String getUserName();
  String getUserId();
}
Run Code Online (Sandbox Code Playgroud)

这是我的测试,但它不正确......

@RunWith(MockitoJUnitRunner.class)
public class UserServiceTest …
Run Code Online (Sandbox Code Playgroud)

java unit-testing mockito spring-boot spring-boot-test

4
推荐指数
1
解决办法
7409
查看次数

Spring Boot中进行单元测试之前,通过data.sql文件向h2数据库插入数据

我想在 spring boot+ JPA 中执行单元测试。为此,我创建了配置文件来为 dataSource、所有 hibernate 属性、entityManagerFactory 和 transactionManager 创建 bean。一切都很完美。表是由模型类创建的。但现在我想通过data.sql文件在数据库的所有表中插入数据进行测试。我将 data.sql 文件保留在 src/main/resources 中,但它没有加载该文件。那么在开始单元测试之前如何在 h2 数据库中加载数据。

这是我的配置文件 -


import java.util.Properties;

import javax.sql.DataSource;

import org.hibernate.cfg.Environment;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;


@Configuration
@EnableJpaRepositories(basePackages = "base_package_name")
@EnableTransactionManagement
public class JPAConfig {

    @Bean
    public DataSource dataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName("org.h2.Driver");
        dataSource.setUrl("jdbc:h2:mem:myDb;DB_CLOSE_DELAY=-1");
        /*dataSource.setDriverClassName("org.hsqldb.jdbcDriver");
        dataSource.setUrl("jdbc:hsqldb:mem:testdb");*/
        dataSource.setUsername("sa");
        dataSource.setPassword("");

        return dataSource;
    } …
Run Code Online (Sandbox Code Playgroud)

java h2 h2db spring-boot spring-boot-test

4
推荐指数
1
解决办法
1万
查看次数

运行 Spring Boot MockMvc 测试时“未找到返回值的转换器”

我正在尝试创建 Spring Boot 控制器的 MockMvc 测试。我特别不希望启动整个应用程序上下文,因此我将上下文限制为有问题的控制器。但是,测试失败并显示 500,并显示以下日志输出:

2020-03-03 13:04:06.904  WARN 8207 --- [           main] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.http.converter.HttpMessageNotWritableException: No converter found for return value of type: class main.endpoints.ResponseDto]
Run Code Online (Sandbox Code Playgroud)

看来 Spring Boot 上下文不知道如何找到 Jackson。

这是控制器

@RestController
class MyController {
    @GetMapping("/endpoint")
    fun endpoint(): ResponseDto {
        return ResponseDto(data = "Some data")
    }
}

data class ResponseDto(val data: String)
Run Code Online (Sandbox Code Playgroud)

测试如下:

@SpringBootTest(
    classes = [MyController::class],
    webEnvironment = SpringBootTest.WebEnvironment.MOCK
)
@AutoConfigureMockMvc
internal class MyControllerTest(@Autowired private val mockMvc: MockMvc) {
    @Test
    fun `should work`() {
        mockMvc.perform(MockMvcRequestBuilders.get("/endpoint").accept(MediaType.APPLICATION_JSON))
            .andExpect( …
Run Code Online (Sandbox Code Playgroud)

jackson kotlin spring-boot spring-boot-test

4
推荐指数
1
解决办法
1818
查看次数

测试中什么时候强制使用TestEntityManager?

拥有一个 Spring Boot 应用程序,使用 Spring Data JPA 和 H2 配置,用于示例/学术目的。

存储库定义为:

public interface PersonaRepository extends CrudRepository<Persona, String> {

}
Run Code Online (Sandbox Code Playgroud)

然后进行以下测试

@ActiveProfiles(profiles={"h2"})
@DataJpaTest
class PersonaRepositorySliceTests {

    @Autowired
    private PersonaRepository personaRepository;

    @Autowired
    private TestEntityManager testEntityManager;

    @Test
    void countTest() {
        long count = personaRepository.count();
        assertThat(count).isEqualTo(33);

        count = testEntityManager.getEntityManager()
                                 .createQuery("SELECT COUNT(*) FROM Persona p")
                                 .getResultList().size();
        System.out.println("count: " + count);//prints 1
        //assertThat(count).isEqualTo(33);//fails

        count = testEntityManager.getEntityManager()
                                 .createNativeQuery("SELECT COUNT(*) FROM persona")
                                 .getResultList().size();

        System.out.println("count: " + count);//prints 1
        assertThat(count).isEqualTo(33);//fails
    }

}
Run Code Online (Sandbox Code Playgroud)

long count = personaRepository.count();
assertThat(count).isEqualTo(33);
Run Code Online (Sandbox Code Playgroud)

通过,因此 …

java spring-boot spring-boot-test

4
推荐指数
1
解决办法
6499
查看次数

如何在@SpringBootTest 中创建可重用的@MockBean 定义?

我有一个@SpringBootTest类,它有一个相当复杂的模拟定义设置,带有模拟的返回值。

问题:我可以将@MockBean设置外部化到一个自己的类中,以便我可以在多个类中重用模拟配置(旁注:我不是在这里寻找继承!)。

@SpringBootTest
public class ServiceTest extends DefaultTest {
    @Autowired
    private ServiceController controller;
    
    @MockBean
    private Service1 s1;
    
    @MockBean
    private Service2 s2;
    
    @MockBean
    private Service3 s3;
    
    //assume more complex mock definitions
    @BeforeEach
    public void mock() {
        when(s1.invoke()).thenReturn(result1);
        when(s2.invoke()).thenReturn(result2);
        when(s3.invoke()).thenReturn(result3);
    }
    
    @Test
    public void test() {
        //...
    }
}
Run Code Online (Sandbox Code Playgroud)

我想相互独立地加载模拟,而不是全局加载我的所有测试。

java junit spring spring-boot-test

4
推荐指数
1
解决办法
119
查看次数

用于测试 Spring Boot 应用程序的初始化 H2 数据库期间出现异常“org.h2.jdbc.JdbcSQLSyntaxErrorException:未找到表“NAME””

我编写用@SpringBootTest注释的集成测试。为了运行测试,我将测试资源中的 data.sql 中的数据插入到 H2 数据库中。

\n

我遇到的情况是,第一次测试成功运行,经过多次后,出现错误,告诉我,H2 无法在表中插入数据,因为找不到该表。每次启动测试时都会出现不同的原始错误。在同一日志中,我看到在异常发生之前该表已创建,并且其他插入已成功执行。我看到我的 5 个测试中有 4 个是绿色的,一个是红色的。不同的时间可能有不同的测试。

\n

重新启动 IDE 可使测试再次成功运行 3-4 次。之后,错误返回。

\n

我尝试将 @DirtiesContext() 与我的测试类和测试方法一起使用,但它没有解决问题。

\n

我猜测问题的根源可能在于我初始化数据库的方式。对于这两种数据库,我都使用一个 data.sql 文件的引用。我没有找到一种方法将它们分成不同的 *.sql 文件。

\n

第二个猜测是在创建表之前就开始插入数据库。我现在通过将所有插入移动到测试代码中来检查这个理论。但我不确定这是否会有所帮助,因为我播种日志是在插入开始之前创建的表。

\n

我在每次测试运行之前使用“mvn clean”。

\n

我将非常感谢您在解决这个问题方面的建议。

\n

我的实体:

\n
@Entity\n@Table(name = "entity1", schema = "schema1")\n@Data\n@Builder\n@NoArgsConstructor\n@AllArgsConstructor\npublic class SomeEntityClass extends GenericEntity<Long> { ...}\n\n\n@MappedSuperclass\npublic abstract class GenericEntity<ID extends Serializable> implements Serializable {\n\n    @Id\n    @GeneratedValue(strategy = GenerationType.IDENTITY)\n    @Column\n\n    protected ID id;\n\n//getter, setter\n}\n\n
Run Code Online (Sandbox Code Playgroud)\n

在我的 data.sql 文件中初始化看起来像这样:

\n
create schema if not exists schema1;\ncreate schema if …
Run Code Online (Sandbox Code Playgroud)

h2 spring-jdbc spring-data-jpa spring-boot spring-boot-test

4
推荐指数
1
解决办法
6991
查看次数

为什么 @Cachable(...) 可以与 @Bean return mock() 一起使用,但不能与 @MockedBean 一起使用

为什么使用时缓存会被值填满

@Autowired
ServiceXY serviceXY

@TestConfiguration
static class AppDefCachingTestConfiguration {
    @Bean
    public ServiceXY ServiceXYMock() {
        return mock(ServiceXY.class);
    }
}
Run Code Online (Sandbox Code Playgroud)

但不与

@MockBean
ServiceXY serviceXY
Run Code Online (Sandbox Code Playgroud)

使用 @MockBean 时,在访问缓存值时会出现 NullPointerException,如我的测试中所示:

@Autowired
ConcurrentMapCacheManager cmcm; 

@Test
void anTest(){
when(serviceXY.methodThatFillsCache(anyString()).thenReturn("ABC");

serviceXY.methodThatFillsCache("TEST1");

cmcm.getCache("Cachename").get("TEST1",String.class).equals("ABC");
...
}
Run Code Online (Sandbox Code Playgroud)

mockito spring-bean spring-boot spring-cache spring-boot-test

4
推荐指数
1
解决办法
639
查看次数

在Spring Boot 2.1中,由于多个@BootstrapWith而不再允许许多测试片

我试图升级由两个测试片(在我的情况下为@JsonTest和@JdbcTest,中间是脆脆的测试代码)制成的美味三明治,为其添加了spring boot 2.1风味。但似乎并没有太大的成功。我无法使用许多@ ... Test注释测试,因为它们现在各自带有自己的XxxTestContextBootstrapper。当他们都使用相同的SpringBootTestContextBootstrapper时,它可以正常工作。

@RunWith(SpringRunner.class)
@JdbcTest
@JsonTest
public class Test {
  @Test
  public void test() { System.out.printn("Hello, World !"); }
}
Run Code Online (Sandbox Code Playgroud)

我从BootstrapUtils收到的错误是llegalStateStateException:配置错误:为测试类找到了@BootstrapWith的多个声明

我知道我在这里可能做错了什么,但是有一种简单的方法可以同时加载Json和Jdbc上下文吗?

spring-boot-test

3
推荐指数
1
解决办法
826
查看次数