I'm thinking I need to setup the db testing environment (e.g. create tables, seed users so that token can be issued with credentials) before I can run tests but not sure how to.
@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());
}
// ...
Here is a typical Entity for this app:
@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;
}
}
But also, as the error indicates, I'd need to generate these oauth* tables too.
Here is my src/test/resources/application.properties
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
So I guess I want to generate the tables (entities, and oauth*) in the H2 database prior to running tests and populate with a single user(?) but can't seem to figure how this is done in Spring Boot. Or should I not be hitting any database and mocking JDBC altogether? Could someone point me in the correct direction as to how to prepare a test environment here? I'm at a bit of a loss.
UPDATE
Here is how dataSource is configured:
@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>