Comment se moquer de DriverManager.getConnection(...)?
J'ai une classe, qui se connecte à un H2 base de données et exécute plusieurs instructions SQL.
public class H2Persistence implements IPersistence {
private Connection conn;
@Override
public void open() {
try
{
Class.forName("org.h2.Driver");
conn = DriverManager.getConnection(CONN_TYPE_USER_HOME);
final Statement stmt = conn.createStatement();
stmt.executeUpdate("CREATE TABLE PERSON(" +
"ID BIGINT,"+
"AGEGROUP VARCHAR(255),"+
"MONTHLY_INCOME_LEVEL VARCHAR(255)," +
"GENDER VARCHAR(1),"+
"HOUSEHOLD_ID BIGINT)");
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
}
...
}
Je veux écrire un test unitaire, qui vérifie, que dans le open
méthode une certaine instruction SQL (DROP TABLE IF EXISTS PERSON
) est exécutée.
Pour ce faire, j'ai écrit test suivant:
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.powermock.api.mockito.PowerMockito.mockStatic;
import static org.powermock.api.mockito.PowerMockito.when;
@RunWith(PowerMockRunner.class)
@PrepareForTest(DriverManager.class)
public class H2PersistenceTest {
@Test
public void testDropPersonIsCalled() throws SQLException {
final Statement statement = mock(Statement.class);
final Connection connection = mock(Connection.class);
when(connection.createStatement()).thenReturn(statement);
mockStatic(DriverManager.class);
when(DriverManager.getConnection(H2Persistence.CONN_TYPE_USER_HOME)).thenReturn
(connection);
final H2Persistence objectUnderTest = new H2Persistence();
objectUnderTest.open();
verify(statement.executeUpdate("DROP TABLE IF EXISTS PERSON"));
}
}
Mais elle ne fonctionne pas - au lieu de se moquer de connexion, DriverManager
retourne lien réel.
Comment puis-je résoudre ce problème (faire DriverManager
raccordement de retour fantaisie dans le test) ?
Voici la pom.xml
de mon projet, peut-être que quelque chose est mal il.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>ru.mycompany</groupId>
<artifactId>myproduct</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<powermock.version>1.5.1</powermock.version>
<maven.compiler.source>1.6</maven.compiler.source>
<maven.compiler.target>1.6</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.easytesting</groupId>
<artifactId>fest-util</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>org.easytesting</groupId>
<artifactId>fest-assert-core</artifactId>
<version>2.0M8</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>15.0</version>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.9.5</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.3.173</version>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>${powermock.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito</artifactId>
<version>${powermock.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Vous devez vous connecter pour publier un commentaire.
Celui-ci fonctionne (attention pour les importations):
La façon habituelle de faire, ce serait facteur de la création de la connexion dans une autre classe, et injecter une instance de la classe en question. Vous pouvez ensuite se moquer de cette nouvelle classe.
Dans votre cas, quelque chose comme ceci:
Dans ce cas particulier, même mieux serait probablement d'utiliser la norme d'interface JDBC
source de données
au lieu de votre propre usine de raccordement classe:DataSource
existe déjà, représente un bien défini, autonome concept, et a implémentations déjà, je pense que le risque de réutilisable overgrowth est petit.