Ich habe eine Klasse, die eine Verbindung zu einer H2-Datenbank herstellt und mehrere SQL-Anweisungen ausführt.Wie man DriverManager.getConnection (...) mockt?
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();
}
}
...
}
Ich möchte einen Komponententest schreiben, der ausgeführt wird, überprüft, dass in dem Verfahren eine bestimmte open
SQL-Anweisung (DROP TABLE IF EXISTS PERSON
).
Um dies zu tun, ich schrieb Test folgende:
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"));
}
}
Aber es funktioniert nicht - statt der Mock-Verbindung, DriverManager
kehrt wirkliche Verbindung.
Wie kann ich es beheben (make DriverManager
Rückverbindung Pseudo im Test)?
Hier ist die pom.xml
meines Projekts, vielleicht ist etwas nicht in Ordnung. eine Instanz, die in die Klasse in Frage
<?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>
Ich habe dies vor getan e (siehe http://altruix.wordpress.com/portfolio/project-control-center/ für Details). Das Problem ist, dass, wenn Sie viele Klassen schreiben, Sie mit viel Code (Interface, Factory Interfaces und deren Implementierungen) enden. Also habe ich versucht, den Vorteil dieses Designs (Testbarkeit) ohne die Kosten (viel Code) zu bekommen. –
Das ist definitiv eine Gefahr, diesen Ansatz beim Schreiben von Scheintests zu verwenden. Ich arbeite an einer Codebasis, bei der ein Großteil der Logik durch die Mühlsteine einer nachgebildeten Umgestaltung zu einem feinen Pulver gemahlen wurde. In diesem Fall, vorausgesetzt, dass "DataSource" bereits existiert, ein wohldefiniertes, in sich geschlossenes Konzept darstellt und Implementierungen bereits aufweist, würde ich denken, dass das Risiko des Übergreifens von Boilerplatten gering ist. –