2016-06-16 3 views
1

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 객체와 생성자 사이에 연결이없는 것 같은 느낌이 들었습니까?

+0

REST 서비스가 단일 책임 원칙을 위반하기 때문에 테스트하기가 어렵습니다. 데이터베이스 로직을 다른 클래스에 캡슐화하면 해당 클래스를 쉽게 조롱하여 REST 서비스를 독립적으로 테스트 할 수있다. 또 다른 공통적 인 접근법은 단위 테스트를 통해 창을 띄우고 통합 테스트를 실행하는 것입니다. 즉, 메모리 내 데이터베이스를 구성하고 모의하지 마십시오. – DavidS

+0

확인. 그래서 데이터베이스 로직을 별도의 클래스에 캡슐화했습니다. 나는 Mockito로 데이터를 조롱하고 싶지만 실제로 어떻게'getAllMovies' 메소드가 조롱 된 클래스를 사용해야한다고 말할 수 있는지 확신 할 수 없다. – RSSD

+0

몇가지 접근법이있다. 귀하의 REST 서비스가 일부 비공개 필드에 대한 액세스 권한을 가지고 있다고 가정합니다. 'moviesDatabase'. 이 객체 나 메소드를 조롱하고 싶기 때문에,'moviesDatabase'를 사용할 REST 서비스를 알리는 방법이 필요하다. 옵션은 다음과 같습니다 : (1) 생성자 삽입 (2) Dagger 또는 Weld와 같은 멋진 의존성 주입 프레임 워크를 사용하여 필드를 package-private로 설정하고 직접 설정합니다 (3). – DavidS

답변

2

당신이 인스턴스를 생성 저지를 말하고있다 클래스

new ResourceConfig(MoviesResource.class) 

로 자원을 등록합니다. DI를 구성하지 않으면 no-arg 생성자를 호출하게됩니다. 인수가없는 생성자에서는 서비스를 직접 작성하는 중입니다. 너의 모의에 대해서는 아무것도 모른다.

대신 리소스 클래스를 인스턴스로 등록해야합니다. 그렇게하면 생성자에게 모의 객체를 전달할 수 있습니다.

MockitoAnnotations.initMocks(this); 
return new ResourceConfig() 
     .register(new MoviesResource(dbr)); 

는 Mockito 러너를 사용하지 마십시오. 대신 MockitoAnnotations.initMocks 방법을 사용하십시오. 그렇게하면 @Mock이 주입 될 때 제어 할 수 있습니다. 러너를 사용한다면, Mockito 주입이 일어나기 전에 configure 메소드가 프레임 워크에 의해 호출되기 때문에 시간 내에 주입이 발생하지 않습니다.

+0

감사합니다. 나는 Mockito 주자를 제거하고'MockitoAnnotations.initMocks (this);를 추가했다. 새로운 ResourceConfig(). register (새로운 MoviesResource (dbr))'코드를 반환하십시오. – RSSD

+1

여러분의 권리는'init'이 아닌'initMocks'이어야합니다 :-) –

관련 문제