当前位置: 首页 > 知识库问答 >
问题:

未找到H2-table“oauth_access_token”的Spring引导测试

巫马化
2023-03-14

我想在运行测试之前,我需要设置db测试环境(例如,创建表,种子用户,以便可以用凭据颁发令牌),但不确定如何运行。

@RunWith(SpringRunner.class)
@WebAppConfiguration
@SpringBootTest(classes = Application.class)
public class UsersControllerTest {

    // ...

    private MockMvc mockMvc;

    @Before
    public void setup() {
        this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac)
          .addFilter(springSecurityFilterChain).build();
    }

    private String obtainAccessToken(String username, String password) throws Exception {

        MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
        params.add("client_id", CLIENTID);
        params.add("grant_type", CLIENTPASSWORD);
        params.add("username", username);
        params.add("password", password);

        ResultActions result = mockMvc.perform(post("/oauth/token")
            .params(params)
            .with(httpBasic(CLIENTID, CLIENTPASSWORD))
            .accept("application/json;charset=UTF-8"))
            .andExpect(status().isOk())
            .andExpect(content().contentType("application/json;charset=UTF-8"));

        String resultString = result.andReturn().getResponse().getContentAsString();

        JacksonJsonParser jsonParser = new JacksonJsonParser();
        return jsonParser.parseMap(resultString).get("access_token").toString();
    }

    @Test
    public void givenNoToken_whenGetAllUsers_thenUnauthorized() throws Exception {

        mockMvc.perform(
            get("/users")
            ).andExpect(status().isUnauthorized());
    }

    @Test
    public void givenToken_whenGetAllUsers_thenOk() throws Exception {
        String accessToken = obtainAccessToken("martyn", "secret");
        mockMvc.perform(
            get("/users")
                .header("Authorization", "Bearer " + accessToken)
            ).andExpect(status().isOk());
    }

    // ...

下面是这个应用程序的一个典型实体:

@Entity(name = "users")
public class User implements Serializable {

    /**
     *
     */
    private static final long serialVersionUID = -8507204786382662588L;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Column(nullable = false)
    private String firstName;

    @Column(nullable = false)
    private String surname;

    @Column(nullable = false, unique = true)
    private String email;

    @Column(nullable = false, unique = true)
    private String username;

    @Column(nullable = false)
    @JsonIgnore
    private String password;

    @OneToMany
    @JoinColumn(name="user_id") // cascade = CascadeType.ALL, orphanRemoval = true
    private List<Fund> funds;

    public Long getId() {
        return id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    // standard getters and setters

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getSurname() {
        return surname;
    }

    public void setSurname(String surname) {
        this.surname = surname;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public List<Fund> getFunds() {
        return funds;
    }
}

但是,正如错误所示,我还需要生成这些oauth*表。

下面是我的src/test/resources/application.

spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.url=jdbc:h2:mem:db;DB_CLOSE_DELAY=-1
spring.datasource.username=sa
spring.datasource.password=sa

因此,我想在运行测试之前在H2数据库中生成表(实体和oauth*),并使用单个用户(?)但似乎不知道这是如何在Spring Boot中实现的。或者我不应该攻击任何数据库并完全嘲笑JDBC吗?有人能告诉我如何在这里准备一个测试环境的正确方向吗?我有点不知所措。

更新

以下是dataSource的配置方式:

@Configuration
public class JDBCTokenConfig {

    @Value("${spring.datasource.url}")
    private String datasourceUrl;

    @Value("${spring.datasource.username}")
    private String dbUsername;

    @Value("${spring.datasource.password}")
    private String dbPassword;

    @Bean
    public DataSource dataSource() {
        final DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setUrl(datasourceUrl);
        dataSource.setUsername(dbUsername);
        dataSource.setPassword(dbPassword);
        return dataSource;
    }

    @Bean
    public TokenStore tokenStore(DataSource dataSource) {
        return new JdbcTokenStore(dataSource);
    }

    // @Bean
    // public TokenStore tokenStore() {
    //     return new InMemoryTokenStore();
    // }
}

pom.xml

<dependencies>
    ...
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>com.h2database</groupId>
        <artifactId>h2</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    ...
</dependencies>

共有1个答案

傅明知
2023-03-14

我认为这是一件好事,以达到您在内存数据库没有嘲笑。老实说,您将需要更多的时间来配置而不是创建数据库所需的正确模式。

使用spring-boot,很容易配置来测试应用程序

  1. 使用spring-boot-starter-jpa
  2. 声明
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <scope>test</scope>
</dependency>

由于@springbootapplication,数据源将自动配置为连接到您的H2 in memory数据库。

还要查看spring文档,了解如何配置hibernate:

  • https://docs.spring.io/spring-boot/docs/current/reference/html/appendix-application-properties.html#data-properties
  • https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#reference

现在我明白了,每个人都明白,您需要根据您的环境进行不同的配置。最好的办法是依靠个人资料。

在您的情况下,您有一个prod概要文件和一个test概要文件。

声明概要文件并将spring.datasource属性保存在src/test/resources/application.properties中(我认为在您的情况下更容易)

我建议您在Spring中阅读memory database中的这个配置,以便进行测试,如果您在配置环境时遇到困难,请告诉我。

有了这个,您将需要:

  • 在测试类的顶部添加注释@activeprofiles('Test')
  • 还原以前删除的spring.datasource属性,并将它们放入src/test/resources/application-test.properties

让我知道

 类似资料:
  • 我目前有一个Spring引导应用程序,其中包含2个配置文件:application.yaml和application-test.yaml.应用程序测试配置文件已正确加载,该文件中的任何设置都按预期工作。 然而,我有一个问题,特别是一个设置是Spring。jpa。冬眠ddl auto='update'。在应用程序中定义此设置时。yaml文件它导致我的JPA单元测试失败,异常为“Table”PG_类“

  • 我的应用程序正在尝试外部化所有项目属性,一些属性将位于我的应用程序中,而另一个属性将位于 Windows 中某处的文件夹中。 我将Spring设置为这样执行:-Spring . config . location = file:///C:\ Temp \ config \ application . properties,class path:application . properties 如您

  • 我有一个rest Spring Boot rest API,我想测试它。我可以在Eclipse中手动运行测试(不使用maven,并通过将应用程序作为JUnit测试运行),它运行良好并显示结果,但是不能“工作”,如下所示。 以下是我的POM文件:

  • 我正在尝试一个使用H2的示例。但我无法创建内存中的DB。运行以下程序时,我只收到一条错误消息: Java语言sql。SQLException:在java上找不到适合jdbc:h2:mem的驱动程序。sql/java。sql。DriverManager。java上的getConnection(DriverManager.java:702)。sql/java。sql。DriverManager。数据库

  • 我试图找出一种最简单的方法来控制基本Spring Boot RESTful服务的404 Not Found处理程序,例如Spring提供的示例: https://spring.io/guides/gs/rest-service/ 而不是让它返回默认的Json输出: 或者有比抛出并处理NoHandlerFoundException更好的方法吗?