ジャージAPIをテストするためにJunit
を使用しています。データベースなしでDAOをテストしたい。 Mockitoを使用しようとしましたが、DBへのHibernate呼び出しを含むDAOをテストするためにモックオブジェクトを使用できません。 DAOを呼び出すヘルパークラス用にJunit
を記述したいと思います。DAOでDB接続をモックするためのサンプルコードを使用して、ソリューションを提供できる人はいますか。
編集:
Status.Java
@GET
@Produces(MediaType.TEXT_PLAIN)
public String getDBValue() throws SQLException {
DatabaseConnectionDAO dbConnectiondao = new DatabaseConnectionDAO();
String dbValue = dbConnectiondao.dbConnection();
return dbValue;
}
DatabaseConnectionDAO.Java
private Connection con;
private Statement stmt;
private ResultSet rs;
private String username;
public String dbConnection() throws SQLException{
try{
Class.forName("com.mysql.jdbc.Driver");
con = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test", "root", "root");
stmt = con.createStatement();
rs =stmt.executeQuery("select * from test");
while(rs.next()){
username = rs.getString(1);
}
}catch(Exception e){
e.printStackTrace();
}finally{
con.close();
}
return username;
}
TestDatabase.Java
@Test
public void testMockDB() throws SQLException{
DatabaseConnectionDAO mockdbDAO = mock(DatabaseConnectionDAO.class);
Connection con = mock(Connection.class);
Statement stmt = mock(Statement.class);
ResultSet rs = mock(ResultSet.class);
Client client = Client.create();
WebResource webResource = client.resource("myurl");
ClientResponse response = webResource.accept(MediaType.TEXT_PLAIN).get(ClientResponse.class);
verify(mockdbDAO).dbConnection();
//when(rs.next()).thenReturn(true);
when(rs.getString(1)).thenReturn(value);
actualResult = response.getEntity(String.class);
assertEquals(expectedResult,actualResult );
}
DAOをどのように嘲笑すべきかという考えを見逃しているのではないかと思います。接続について心配する必要はありません。一般に、メソッドが呼び出されたときに何が起こるかをモックしたいだけです。たとえば、findXxx
メソッドです。たとえば、このDAOインターフェイスがあるとします
public interface CustomerDAO {
public Customer findCustomerById(long id);
}
あなたはそれを次のようにモックすることができます
CustomerDAO customerDao = Mockito.mock(CustomerDAO.class);
Mockito.when(customerDao.findCustomerById(Mockito.anyLong()))
.thenReturn(new Customer(1, "stackoverflow"));
次に、そのモックされたインスタンスを、それに依存するクラスに「注入」する必要があります。たとえば、リソースクラスで必要な場合は、コンストラクターを介して注入できます。
@Path("/customers")
public class CustomerResource {
CustomerDAO customerDao;
public CustomerResource() {}
public CustomerResource(CustomerDAO customerDao) {
this.customerDao = customerDao;
}
@GET
@Path("/{id}")
@Produces(MediaType.APPLICATION_JSON)
public Response findCustomer(@PathParam("id") long id) {
Customer customer = customerDao.findCustomerById(id);
if (customer == null) {
throw new WebApplicationException(Response.Status.NOT_FOUND);
}
return Response.ok(customer).build();
}
}
...
new CustomerResource(customerDao)
いいえ、findCustomer
メソッドを押すと、DAOは常にモックされたDAOで顧客を返します。
これがJerseyTestFrameworkを使用した完全なテストです
public class CustomerResourceTest extends JerseyTest {
private static final String RESOURCE_PKG = "jersey1.stackoverflow.standalone.resource";
public static class AppResourceConfig extends PackagesResourceConfig {
public AppResourceConfig() {
super(RESOURCE_PKG);
CustomerDAO customerDao = Mockito.mock(CustomerDAO.class);
Mockito.when(customerDao.findCustomerById(Mockito.anyLong()))
.thenReturn(new Customer(1, "stackoverflow"));
getSingletons().add(new CustomerResource(customerDao));
}
}
@Override
public WebAppDescriptor configure() {
return new WebAppDescriptor.Builder()
.initParam(WebComponent.RESOURCE_CONFIG_CLASS,
AppResourceConfig.class.getName()).build();
}
@Override
public TestContainerFactory getTestContainerFactory() {
return new GrizzlyWebTestContainerFactory();
}
@Test
public void testMockedDAO() {
WebResource resource = resource().path("customers").path("1");
String json = resource.get(String.class);
System.out.println(json);
}
}
Customer
クラスは、long id
とString name
を持つ単純なPOJOです。ジャージーテストフレームワークの依存関係は
<dependency>
<groupId>com.Sun.jersey.jersey-test-framework</groupId>
<artifactId>jersey-test-framework-grizzly2</artifactId>
<version>1.19</version>
<scope>test</scope>
</dependency>
上記の例では、OPがJersey 1を使用していることを確認したので、Jersey 1を使用しています。Jersey2(アノテーションインジェクションあり)を使用した完全な例については、 この投稿 を参照してください。
短い答えだけしないでください!
単体テストが必要なコードはDAOのクライアントであるため、モックする必要があるのはDAOです。 DAOは、アプリを外部システム(ここではデータベース)と統合するコンポーネントであるため、統合テストとして(つまり、実際のデータベースで)テストする必要があります。