how to create a Mock database and add data in mock db for integration testing using postgres db and java

huangapple go评论70阅读模式
英文:

how to create a Mock database and add data in mock db for integration testing using postgres db and java

问题

我想进行集成测试,为此我想创建一个测试数据库并添加一些数据。
在进行集成测试时,我应该如何指向测试数据库?

感谢您的帮助......

英文:

I want to perform the Integration test for which I want to create a test DB and add some data.
how should I point to the test DB while doing an integration test?

Thanks for Help......

答案1

得分: 2

以下是翻译好的部分:

你可以使用 testcontainers 来实现这个。你可以观看这个 视频 来了解关于这个的想法,以及如何在你的 Spring Boot 应用程序中配置它。

对于你的 Spring 集成测试,创建一个如下所示的配置:

AbstractIT.java

@Testcontainers
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, properties = {"spring.main.allow-bean-definition-overriding=true"})
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) // 不要用内存数据库替换我们的数据库
@ContextConfiguration(initializers = AbstractIT.DockerPostgresDataSourceInitializer.class)
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public abstract class AbstractIT {

    private static PostgreSQLContainer<?> postgresDBContainer = new PostgreSQLContainer<>("postgres:9.6")
            .withUrlParam("TC_DAEMON", "true")
            .withFileSystemBind("docker/db", "/docker-entrypoint-initdb.d", BindMode.READ_WRITE);

    static {
        postgresDBContainer.start();
    }

    public static class DockerPostgresDataSourceInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {

        @Override
        public void initialize(ConfigurableApplicationContext applicationContext) {
            Assertions.assertNotNull(applicationContext);
            TestPropertySourceUtils.addInlinedPropertiesToEnvironment(
                    applicationContext,
                    "spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true",
                    "spring.datasource.driver-class-name=" + postgresDBContainer.getDriverClassName(),
                    "spring.datasource.url=" + postgresDBContainer.getJdbcUrl(),
                    "spring.datasource.username=" + postgresDBContainer.getUsername(),
                    "spring.datasource.password=" + postgresDBContainer.getPassword()
            );
        }
    }
}

现在你可以按照下面的示例,在你的集成测试中编写代码:

UserControllerIT.java

class UserControllerIT extends AbstractIT {

    @Autowired
    private TestRestTemplate template;

    @Autowired
    private UserRepository userRepository;

    @Test
    @Order(1)
    @DisplayName("测试获取所有用户详情")
    void getAllUsersTest() {
        ResponseEntity<List<UserDTO>> response = this.template.exchange("/v1/users", GET, HttpEntity.EMPTY, new ParameterizedTypeReference<List<UserDTO>>() {
        });
        assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
        assertThat(response.getBody())
                .isNotEmpty()
                .hasSize(3)
                .extracting(UserDTO::getEmail).containsAnyOf("user1@some.com");
    }

    // 其他测试方法的翻译...

    private UserDTO buildUserRequest() {
        return UserDTO.builder()
                .email("user4@some.com")
                .lastName("Maria")
                .firstName("Fernandes")
                .build();
    }

    private Map<String, String> singleParam(String key, String value) {
        Map<String, String> params = new HashMap<>();
        params.put(key, value);
        return params;
    }
}

你可以在这个 Github 仓库中找到完整的运行中应用程序 - https://github.com/nidhishkrishnan/stackoverflow/tree/master/employee-testcontainer

英文:

You can use testcontainers for achieving this. You can watch this video to get an idea about this and how to configure it in your spring boot application

For your spring integration test create a configuration like as shown below

AbstractIT.java

@Testcontainers
@SpringBootTest(webEnvironment= SpringBootTest.WebEnvironment.RANDOM_PORT, properties = {&quot;spring.main.allow-bean-definition-overriding=true&quot;})
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) // don&#39;t replace our DB with an in-memory one
@ContextConfiguration(initializers = AbstractIT.DockerPostgresDataSourceInitializer.class)
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public abstract class AbstractIT {

    private static PostgreSQLContainer&lt;?&gt; postgresDBContainer = new PostgreSQLContainer&lt;&gt;(&quot;postgres:9.6&quot;)
            .withUrlParam(&quot;TC_DAEMON&quot;, &quot;true&quot;)
            .withFileSystemBind(&quot;docker/db&quot;, &quot;/docker-entrypoint-initdb.d&quot;, BindMode.READ_WRITE);

    static {
        postgresDBContainer.start();
    }

    public static class DockerPostgresDataSourceInitializer implements ApplicationContextInitializer&lt;ConfigurableApplicationContext&gt; {

        @Override
        public void initialize(ConfigurableApplicationContext applicationContext) {
            Assertions.assertNotNull(applicationContext);
            TestPropertySourceUtils.addInlinedPropertiesToEnvironment(
                    applicationContext,
                    &quot;spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true&quot;,
                    &quot;spring.datasource.driver-class-name=&quot;+postgresDBContainer.getDriverClassName(),
                    &quot;spring.datasource.url=&quot; + postgresDBContainer.getJdbcUrl(),
                    &quot;spring.datasource.username=&quot; + postgresDBContainer.getUsername(),
                    &quot;spring.datasource.password=&quot; + postgresDBContainer.getPassword()
            );
        }
    }
}

Now you can write your Integration test like as shown in the below sample example

UserControllerIT.java

class UserControllerIT extends AbstractIT {

    @Autowired
    private TestRestTemplate template;

    @Autowired
    private UserRepository userRepository;

    @Test
    @Order(1)
    @DisplayName(&quot;Testing to get all the user details&quot;)
    void getAllUsersTest() {
        ResponseEntity&lt;List&lt;UserDTO&gt;&gt; response = this.template.exchange(&quot;/v1/users&quot;, GET, HttpEntity.EMPTY, new ParameterizedTypeReference&lt;List&lt;UserDTO&gt;&gt;() {
        });
        assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
        assertThat(response.getBody())
                .isNotEmpty()
                .hasSize(3)
                .extracting(UserDTO::getEmail).containsAnyOf(&quot;user1@some.com&quot;);
    }

    @Test
    @Order(2)
    @DisplayName(&quot;Testing for saving user details&quot;)
    void saveUsersTest() {
        ResponseEntity&lt;Void&gt; response = this.template.postForEntity(&quot;/v1/users&quot;, new HttpEntity&lt;&gt;(buildUserRequest()), Void.class);
        assertThat(response.getStatusCode()).isEqualTo(HttpStatus.CREATED);
        long usersCount = userRepository.count();
        assertThat(usersCount).isEqualTo(4);
    }

    @Test
    @Order(3)
    @DisplayName(&quot;Testing to deleting user details by id&quot;)
    void deleteUsersTest() {

        this.template.delete(&quot;/v1/users/{id}&quot;, singleParam(&quot;id&quot;, &quot;21&quot;));

        boolean userExists = userRepository.existsById(21L);
        assertThat(userExists).isFalse();
    }

    @Test
    @Order(4)
    @DisplayName(&quot;Testing to finding user details by id&quot;)
    void findUserByIdTest() {
        ResponseEntity&lt;UserDTO&gt; response = this.template.getForEntity(&quot;/v1/users/{id}&quot;, UserDTO.class, singleParam(&quot;id&quot;, &quot;22&quot;));

        assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);

        assertThat(response.getBody())
                .extracting(UserDTO::getEmail, UserDTO::getFirstName, UserDTO::getLastName)
                .containsExactly(&quot;user2@some.com&quot;, &quot;John&quot;, &quot;Duke&quot;);
    }

    private UserDTO buildUserRequest() {
        return UserDTO.builder()
                .email(&quot;user4@some.com&quot;)
                .lastName(&quot;Maria&quot;)
                .firstName(&quot;Fernandes&quot;)
                .build();
    }

    private Map&lt;String, String&gt; singleParam(String key, String value) {
        Map&lt;String, String&gt; params = new HashMap&lt;&gt;();
        params.put(key, value);
        return params;
    }
}

You can see the full running application under this Github Repo - https://github.com/nidhishkrishnan/stackoverflow/tree/master/employee-testcontainer

huangapple
  • 本文由 发表于 2020年4月3日 21:42:02
  • 转载请务必保留本文链接:https://go.coder-hub.com/61013260.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定