繁体   English   中英

JAXRS + JerseyTest测试REST服务

[英]JAXRS + JerseyTest testing a REST Service

我已经使用GET,POST,UPDATE和DELETE四种方法创建了Rest服务。 这些方法连接到数据库以检索和存储数据。

现在,我想测试每种方法。 我为此使用了Jersey测试框架。 只要删除代码,真正对数据库进行调用的代码就可以正常工作。 当我留下进行数据库调用的代码时,它抛出了一个异常,即它无法连接到数据库。

编辑:我做了一些研究,并使用了依赖注入。 数据库调用移到一个单独的类,但我仍然在做错什么。

数据库结果。 在此类中,将调用数据库。

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;
    }
}

包含REST方法的MoviesResource

@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));
}

目前,我可以运行测试,但是当我测试getAllMovies()方法时,它会调用真实数据库,而不是返回jsonObject

我感觉到模拟对象和MovieResource类的构造函数之间缺少连接?

当您将资源注册为课程时

new ResourceConfig(MoviesResource.class)

您要告诉Jersey创建实例。 如果您没有配置任何DI,它将仅调用no-arg构造函数。 在无参数构造函数中,您只是自己创建服务。 它对您的模拟一无所知。

相反,您应该做的是将资源类注册为实例。 这样,您可以将模拟传递给构造函数。

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

不要使用Mockito赛跑者。 而是使用MockitoAnnotations.initMocks方法。 这样,您可以控制何时注入@Mock 如果使用流道,则注入不会及时发生,因为在Mockito注入发生之前框架会调用configure方法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM