GET, POST, UPDATE 및 DELETE의 네 가지 메소드로 Rest 서비스를 만들었습니다. 이 메소드는 데이터베이스에 연결하여 데이터를 검색하고 저장합니다.JAXRS + JerseyTest REST 서비스 테스트
이제 각 방법을 테스트하고 싶습니다. 나는 이것을 위해 저지 테스트 프레임 워크를 사용했다. 그리고 실제로 데이터베이스에 호출하는 코드를 제거하는 한 계속 작동합니다. 데이터베이스를 호출하는 코드를 남겨두면 예외가 발생하여 데이터베이스에 연결할 수 없습니다.
편집 : 일부 연구를 수행하고 의존성 주입을 사용했습니다. db 호출은 별도의 클래스로 옮겨졌지만 여전히 잘못된 것이 있습니다.
DatabaseResults. 이 클래스에서는 DB에 대한 호출이 수행됩니다. 나는 getAllMovies()
방법을 테스트 할 때 나머지 방법
@Path("movies")
public class MoviesResource {
....
private DatabaseResults dbResults = null;
public MoviesResource() {
this(new DatabaseResults());
}
MoviesResource(DatabaseResults dbr){
this.dbResults = dbr;
}
....
@GET
@Produces(MediaType.APPLICATION_JSON)
public Response getAllMovies() throws JSONException, SQLException {
return Response.status(200).entity(dbResults.getAllMovies().toString()).build();
}
내가 테스트하지만 여전히를 실행할 수있는이 순간에 테스트 클래스
@RunWith(MockitoJUnit44Runner.class)
public class MovieResourceTest extends JerseyTest {
JSONObject jsonObject = new JSONObject();
@Mock
DatabaseResults dbr;
@Before
public void setup() throws SQLException{
jsonObject.put("id", "hello");
when(dbr.getAllMovies()).thenReturn(jsonObject);
}
Client client = ClientBuilder.newClient();
WebTarget target = client
.target("http://localhost:9998/RestServiceMovies/resources");
@Override
protected Application configure() {
return new ResourceConfig(MoviesResource.class);
}
@Test
public void getAllMoviesTest() throws SQLException {
String responseGetAllMovies = target("/movies").request().get(String.class);
Assert.assertTrue("hello".equals(responseGetAllMovies));
}
을 포함
public class DatabaseResults {
private final String getQuery = "SELECT * FROM movies";
private Connection connection = null;
private PreparedStatement pstmt = null;
private final ArrayList<Movie> jsonList = new ArrayList<>();
public JSONObject getAllMovies() throws SQLException {
try {
ComboPooledDataSource dataSource = DatabaseUtility.getDataSource();
connection = dataSource.getConnection();
pstmt = connection.prepareStatement(getQuery);
ResultSet rs = pstmt.executeQuery();
while (rs.next()) {
jsonList.add(new Movie(rs.getString(1), rs.getString(2), rs.getString(4), rs.getString(3)));
}
} catch (SQLException ex) {
System.out.println(ex);
System.out.println("Could not retrieve a connection");
connection.rollback();
} finally {
connection.close();
}
JSONObject jsonObject = new JSONObject();
jsonObject.put("movies", jsonList);
return jsonObject;
}
}
MoviesResource 그것은 호출합니다 jsonObject
을 반환하는 대신 실제 데이터베이스에 저장합니다.
MovieResource 클래스의 mock 객체와 생성자 사이에 연결이없는 것 같은 느낌이 들었습니까?
REST 서비스가 단일 책임 원칙을 위반하기 때문에 테스트하기가 어렵습니다. 데이터베이스 로직을 다른 클래스에 캡슐화하면 해당 클래스를 쉽게 조롱하여 REST 서비스를 독립적으로 테스트 할 수있다. 또 다른 공통적 인 접근법은 단위 테스트를 통해 창을 띄우고 통합 테스트를 실행하는 것입니다. 즉, 메모리 내 데이터베이스를 구성하고 모의하지 마십시오. – DavidS
확인. 그래서 데이터베이스 로직을 별도의 클래스에 캡슐화했습니다. 나는 Mockito로 데이터를 조롱하고 싶지만 실제로 어떻게'getAllMovies' 메소드가 조롱 된 클래스를 사용해야한다고 말할 수 있는지 확신 할 수 없다. – RSSD
몇가지 접근법이있다. 귀하의 REST 서비스가 일부 비공개 필드에 대한 액세스 권한을 가지고 있다고 가정합니다. 'moviesDatabase'. 이 객체 나 메소드를 조롱하고 싶기 때문에,'moviesDatabase'를 사용할 REST 서비스를 알리는 방법이 필요하다. 옵션은 다음과 같습니다 : (1) 생성자 삽입 (2) Dagger 또는 Weld와 같은 멋진 의존성 주입 프레임 워크를 사용하여 필드를 package-private로 설정하고 직접 설정합니다 (3). – DavidS