Shuji Watanabe avatar Shuji Watanabe committed acca6bf

12章のコードを追加

Comments (0)

Files changed (20)

database-test/.classpath

+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" output="target/classes" path="src/main/java"/>
+	<classpathentry kind="src" output="target/test-classes" path="src/test/java"/>
+	<classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
+	<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER"/>
+	<classpathentry kind="output" path="target/classes"/>
+</classpath>

database-test/.project

+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>database-test</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>

database-test/.settings/org.eclipse.core.resources.prefs

+eclipse.preferences.version=1
+encoding//src/main/java=utf-8
+encoding//src/test/java=utf-8
+encoding//src/test/resources=utf-8
+encoding/<project>=utf-8

database-test/.settings/org.eclipse.jdt.core.prefs

+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.source=1.6

database-test/.settings/org.eclipse.m2e.core.prefs

+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1

database-test/README.txt

+
+
+リスト12.1  src/test/java/databasetest/H2DatabaseServer.java
+リスト12.2  src/main/java/databasetest/UserDao.java
+リスト12.3  src/test/java/databasetest/DbUnitTester.java
+リスト12.4  src/test/java/databasetest_junit3/UserDaoTest.java
+リスト12.5  src/test/java/databasetest/DbUnitTesterExample.java
+リスト12.6  src/test/resources/databasetest/fixtures.xml
+リスト12.7  src/test/java/databasetest_junit3/UserDaoTest.java
+リスト12.8  src/test/java/databasetest/ITableMatcher.java
+リスト12.9  src/test/java/databasetest/UserDaoTest.java
+リスト12.10 src/test/java/databasetest/UserDaoTest.java
+

database-test/pom.xml

+<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>practicejunit</groupId>
+  <artifactId>database-test</artifactId>
+  <version>1.0.0</version>
+  <properties>
+    <project.build.sourceEncoding>utf-8</project.build.sourceEncoding>
+  </properties>
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <version>2.3.2</version>
+        <configuration>
+          <source>1.6</source>
+          <target>1.6</target>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-surefire-plugin</artifactId>
+        <version>2.11</version>
+        <configuration>
+          <includes>
+            <include>**/*Test.java</include>
+          </includes>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.jacoco</groupId>
+        <artifactId>jacoco-maven-plugin</artifactId>
+        <version>0.5.7.201204190339</version>
+      </plugin>
+    </plugins>
+  </build>
+  <dependencies>
+    <dependency>
+      <groupId>com.h2database</groupId>
+      <artifactId>h2</artifactId>
+      <version>1.3.167</version>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>4.10</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.dbunit</groupId>
+      <artifactId>dbunit</artifactId>
+      <version>2.4.8</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-simple</artifactId>
+      <version>1.5.4</version>
+    </dependency>
+  </dependencies>
+</project>

database-test/src/main/java/databasetest/UserDao.java

+package databasetest;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * リスト12.2 ユーザテーブルにアクセスするためのDAOクラス
+ * @author shuji.w6e
+ */
+public class UserDao {
+
+    public List<String> getList() throws SQLException {
+        ResultSet rs = createStatement().executeQuery("SELECT name FROM users");
+        LinkedList<String> result = new LinkedList<String>();
+        while (rs.next()) {
+            result.add(rs.getString(1));
+        }
+        return result;
+    }
+
+    public void insert(String username) throws SQLException {
+        String sql = "INSERT INTO users(name) VALUES('" + username + "')";
+        createStatement().executeUpdate(sql);
+    }
+
+    private Statement createStatement() throws SQLException {
+        String url = "jdbc:h2:tcp://localhost/db;SCHEMA=ut";
+        Connection connection = DriverManager.getConnection(url, "sa", "");
+        return connection.createStatement();
+    }
+}

database-test/src/test/java/databasetest/DbUnitTester.java

+package databasetest;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+
+import org.dbunit.AbstractDatabaseTester;
+import org.dbunit.database.DatabaseConfig;
+import org.dbunit.database.DatabaseConnection;
+import org.dbunit.database.IDatabaseConnection;
+import org.dbunit.dataset.IDataSet;
+import org.dbunit.ext.h2.H2DataTypeFactory;
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+
+/**
+ * リスト12.3 DbUnitを利用するためのRuleクラス
+ * @author shuji.w6e
+ */
+public abstract class DbUnitTester extends AbstractDatabaseTester implements TestRule {
+
+    private final String connectionUrl;
+    private final String username;
+    private final String password;
+
+    public DbUnitTester(String driverClass, String connectionUrl) {
+        this(driverClass, connectionUrl, null, null);
+    }
+
+    public DbUnitTester(String driverClass, String connectionUrl, String username, String password) {
+        this(driverClass, connectionUrl, username, password, null);
+    }
+
+    public DbUnitTester(String driverClass, String connectionUrl, String username, String password, String schema) {
+        super(schema);
+        this.connectionUrl = connectionUrl;
+        this.username = username;
+        this.password = password;
+        assertNotNullNorEmpty("driverClass", driverClass);
+        try {
+            // JDBCドライバのロード
+            Class.forName(driverClass);
+        } catch (ClassNotFoundException e) {
+            throw new AssertionError(e);
+        }
+    }
+
+    @Override
+    public IDatabaseConnection getConnection() throws Exception {
+        Connection conn = null;
+        if (username == null && password == null) {
+            conn = DriverManager.getConnection(connectionUrl);
+        } else {
+            conn = DriverManager.getConnection(connectionUrl, username, password);
+        }
+        DatabaseConnection dbConnection = new DatabaseConnection(conn, getSchema());
+        DatabaseConfig config = dbConnection.getConfig();
+        config.setProperty(DatabaseConfig.PROPERTY_DATATYPE_FACTORY, new H2DataTypeFactory());
+        return dbConnection;
+    }
+
+    protected void executeQuery(String sql) throws Exception {
+        Connection conn = getConnection().getConnection();
+        conn.createStatement().execute(sql);
+        conn.commit();
+        conn.close();
+    }
+
+    protected void before() throws Exception {
+    }
+
+    protected void after() throws Exception {
+    }
+
+    abstract protected IDataSet createDataSet() throws Exception;
+
+    @Override
+    public Statement apply(final Statement base, Description description) {
+        return new Statement() {
+
+            @Override
+            public void evaluate() throws Throwable {
+                before();
+                setDataSet(createDataSet());
+                onSetup();
+                try {
+                    base.evaluate();
+                } finally {
+                    try {
+                        after();
+                    } finally {
+                        onTearDown();
+                    }
+                }
+            }
+        };
+    }
+
+}

database-test/src/test/java/databasetest/DbUnitTesterExample.java

+package databasetest;
+
+import org.dbunit.dataset.IDataSet;
+import org.dbunit.dataset.xml.FlatXmlDataSetBuilder;
+import org.junit.Rule;
+
+/**
+ * リスト12.5
+ * @author shuji.w6e
+ */
+public interface DbUnitTesterExample {
+
+    @Rule
+    public DbUnitTester tester = new DbUnitTester(
+            "org.h2.Driver", "jdbc:h2:tcp://localhost/db;SCHEMA=ut", 
+            "sa", "", "ut") {
+        
+        @Override
+        protected void before() throws Exception {
+            executeQuery("DROP TABLE IF EXISTS users");
+            executeQuery("CREATE TABLE users(id INT AUTO INCREMENT, name VARCHAR(255))");
+        }
+
+        @Override
+        protected IDataSet createDataSet() throws Exception {
+            return new FlatXmlDataSetBuilder()
+                .build(getClass().getResourceAsStream("fixtures.xml"));
+        }
+    };
+}

database-test/src/test/java/databasetest/H2DatabaseServer.java

+package databasetest;
+
+import java.sql.Connection;
+import java.util.Properties;
+
+import org.h2.tools.Server;
+import org.h2.util.JdbcUtils;
+import org.junit.rules.ExternalResource;
+
+/**
+ * リスト12.1 H2 Databaseサーバを起動/停止するルール
+ * @author shuji.w6e
+ */
+public class H2DatabaseServer extends ExternalResource {
+
+    private final String baseDir;
+    private final String dbName;
+    private final String schemaName;
+    private Server server = null;
+
+    public H2DatabaseServer(String baseDir, String dbName, String schemaName) {
+        this.baseDir = baseDir;
+        this.dbName = dbName;
+        this.schemaName = schemaName;
+    }
+
+    @Override
+    protected void before() throws Throwable {
+        // DBサーバの起動
+        server = Server.createTcpServer("-baseDir", baseDir);
+        server.start();
+        // スキーマの設定
+        Properties props = new Properties();
+        props.setProperty("user", "sa");
+        props.setProperty("password", "");
+        String url = "jdbc:h2:" + server.getURL() + "/" + dbName;
+        Connection conn = org.h2.Driver.load().connect(url, props);
+        try {
+            conn.createStatement().execute("CREATE SCHEMA IF NOT EXISTS " + schemaName);
+        } finally {
+            JdbcUtils.closeSilently(conn);
+        }
+    }
+
+    @Override
+    protected void after() {
+        // DBサーバの停止
+        server.shutdown();
+    }
+}

database-test/src/test/java/databasetest/ITableMatcher.java

+package databasetest;
+
+import org.dbunit.DatabaseUnitException;
+import org.dbunit.DatabaseUnitRuntimeException;
+import org.dbunit.dataset.ITable;
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+import org.junit.internal.matchers.TypeSafeMatcher;
+
+/**
+ * リスト12.8 ITableを比較検証するMatcher
+ * @author shuji.w6e
+ */
+public class ITableMatcher extends TypeSafeMatcher<ITable> {
+
+    public static Matcher<ITable> tableOf(ITable expected) {
+        return new ITableMatcher(expected);
+    }
+
+    private final ITable expected;
+    String assertionMsg = null;
+
+    ITableMatcher(ITable expected) {
+        this.expected = expected;
+    }
+
+    @Override
+    public boolean matchesSafely(ITable actual) {
+        try {
+            org.dbunit.Assertion.assertEquals(expected, actual);
+        } catch (DatabaseUnitException e) {
+            throw new DatabaseUnitRuntimeException(e);
+        } catch (AssertionError e) {
+            assertionMsg = e.getMessage();
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public void describeTo(Description desc) {
+        desc.appendValue(expected);
+        if (assertionMsg == null) return;
+        desc.appendText("\n  >>>").appendText(assertionMsg);
+    }
+
+}

database-test/src/test/java/databasetest/UserDaoTest.java

+package databasetest;
+
+import static databasetest.ITableMatcher.*;
+import static org.hamcrest.CoreMatchers.*;
+import static org.junit.Assert.*;
+
+import java.io.InputStream;
+import java.util.List;
+
+import org.dbunit.dataset.ITable;
+import org.dbunit.dataset.xml.FlatXmlDataSetBuilder;
+import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.runners.Enclosed;
+import org.junit.runner.RunWith;
+
+/**
+ * リスト12.9 assertThatによるITableの比較検証
+ * リスト12.10 コンテキストごとに整理したUserDaoTest
+ * @author shuji.w6e
+ */
+@RunWith(Enclosed.class)
+public class UserDaoTest {
+
+    public static class usersに2件のレコードがある場合 {
+        @ClassRule
+        public static H2DatabaseServer server = new H2UtDatabaseServer();
+        @Rule
+        public DbUnitTester tester = new UserDaoDbUNitTeser("fixtures.xml");
+        UserDao sut;
+
+        @Before
+        public void setUp() throws Exception {
+            this.sut = new UserDao();
+        }
+
+        @Test
+        public void getListで2件取得できる事() throws Exception {
+            // Exercise
+            List<String> actual = sut.getList();
+            // Verify
+            assertThat(actual, is(notNullValue()));
+            assertThat(actual.size(), is(2));
+            assertThat(actual.get(0), is("Ichiro"));
+            assertThat(actual.get(1), is("Jiro"));
+        }
+
+        @Test
+        public void insertで1件追加できる() throws Exception {
+            // Exercise
+            sut.insert("Saburou");
+            // Verify
+            ITable actual = tester.getConnection().createDataSet().getTable("users");
+            InputStream expectedIn = getClass().getResourceAsStream("expected.xml");
+            ITable expected = new FlatXmlDataSetBuilder().build(expectedIn).getTable("users");
+            assertThat(actual, is(tableOf(expected)));
+        }
+    }
+
+    public static class usersに0件のレコードがある場合 {
+        @ClassRule
+        public static H2DatabaseServer server = new H2UtDatabaseServer();
+        @Rule
+        public DbUnitTester tester = new UserDaoDbUNitTeser("zero_fixtures.xml");
+
+        UserDao sut;
+
+        @Before
+        public void setUp() throws Exception {
+            this.sut = new UserDao();
+        }
+
+        @Test
+        public void getListで0件取得できる事() throws Exception {
+            // Exercise
+            List<String> actual = sut.getList();
+            // Verify
+            assertThat(actual, is(notNullValue()));
+            assertThat(actual.size(), is(0));
+        }
+
+        @Test
+        public void insertで1件追加できる() throws Exception {
+            // Exercise
+            sut.insert("Sirou");
+            // Verify
+            ITable actual = tester.getConnection().createDataSet().getTable("users");
+            InputStream expectedIn = getClass().getResourceAsStream("zero_expected.xml");
+            ITable expected = new FlatXmlDataSetBuilder().build(expectedIn).getTable("users");
+            assertThat(actual, is(tableOf(expected)));
+        }
+    }
+
+    static class H2UtDatabaseServer extends H2DatabaseServer {
+        public H2UtDatabaseServer() {
+            super("h2", "db", "ut");
+        }
+    }
+
+    static class UserDaoDbUNitTeser extends DbUnitTester {
+        private final String fixture;
+        public UserDaoDbUNitTeser(String fixture) {
+            super("org.h2.Driver", "jdbc:h2:tcp://localhost/db;SCHEMA=ut", "sa", "", "ut");
+            this.fixture = fixture;
+        }
+        
+        @Override
+        protected void before() throws Exception {
+            executeQuery("DROP TABLE IF EXISTS users");
+            executeQuery("CREATE TABLE users(id INT AUTO_INCREMENT, name VARCHAR(255))");
+        }
+
+        @Override
+        protected org.dbunit.dataset.IDataSet createDataSet() throws Exception {
+            return new FlatXmlDataSetBuilder().build(getClass().getResourceAsStream(fixture));
+        }
+    }
+
+}

database-test/src/test/java/databasetest_junit3/UserDaoTest.java

+package databasetest_junit3;
+
+import static org.dbunit.PropertiesBasedJdbcDatabaseTester.*;
+
+import java.io.InputStream;
+import java.sql.Connection;
+import java.util.Properties;
+
+import org.dbunit.DBTestCase;
+import org.dbunit.dataset.IDataSet;
+import org.dbunit.dataset.ITable;
+import org.dbunit.dataset.xml.FlatXmlDataSetBuilder;
+import org.h2.tools.Server;
+import org.h2.util.JdbcUtils;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+
+public class UserDaoTest extends DBTestCase {
+    
+    static String BASE_DIR = "h2";
+    static String DB_NAME = "db";
+    static String SCHEMA_NAME = "ut";
+    static Server SERVER;
+    @BeforeClass
+    static public void setUpClass() throws Exception {
+        // DBサーバの起動
+        SERVER = Server.createTcpServer("-baseDir", BASE_DIR);
+        SERVER.start();
+        // スキーマの設定
+        Properties props = new Properties();
+        props.setProperty("user", "sa");
+        props.setProperty("password", "");
+        String url = "jdbc:h2:" + SERVER.getURL() + "/" + DB_NAME;
+        Connection conn = org.h2.Driver.load().connect(url, props);
+        try {
+            conn.createStatement().execute("CREATE SCHEMA IF NOT EXISTS " + SCHEMA_NAME);
+        } finally {
+            JdbcUtils.closeSilently(conn);
+        }
+    }
+    
+    @AfterClass
+    static public void tearDownClass() throws Exception {
+        // DBサーバの停止
+        SERVER.shutdown();
+    }
+
+    public UserDaoTest(String name) {
+        super(name);
+        System.setProperty(DBUNIT_DRIVER_CLASS, "org.h2.Driver");
+        System.setProperty(DBUNIT_CONNECTION_URL, "jdbc:h2:tcp://localhost/db;SCHEMA=ut");
+        System.setProperty(DBUNIT_USERNAME, "sa");
+        System.setProperty(DBUNIT_PASSWORD, "");
+        System.setProperty(DBUNIT_SCHEMA, "ut");
+    }
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+    }
+
+    @Override
+    protected IDataSet getDataSet() throws Exception {
+        return new FlatXmlDataSetBuilder().build(getClass().getResourceAsStream("fixtures.xml"));
+    }
+
+    public void testアサーション例() throws Exception {
+        // 期待されるusersテーブルのデータセット
+        InputStream expectedIn = getClass().getResourceAsStream("expected.xml");
+        ITable expected = new FlatXmlDataSetBuilder().build(expectedIn).getTable("users");
+        // 実データベースが保持するusersテーブルのデータセット
+        ITable actual = super.getConnection().createDataSet().getTable("users");
+        // アサーション
+        org.dbunit.Assertion.assertEquals(expected, actual);
+    }
+    
+
+}

database-test/src/test/resources/databasetest/expected.xml

+<dataset>
+	<users id="1" name="Ichiro" />
+	<users id="2" name="Jiro" />
+	<users id="3" name="Saburou" />
+</dataset>

database-test/src/test/resources/databasetest/fixtures.xml

+<dataset>
+	<users id="1" name="Ichiro" />
+	<users id="2" name="Jiro" />
+</dataset>

database-test/src/test/resources/databasetest/zero_expected.xml

+<dataset>
+	<users id="1" name="Sirou" />
+</dataset>

database-test/src/test/resources/databasetest/zero_fixtures.xml

+<dataset>
+  <users />
+</dataset>

database-test/src/test/resources/databasetest_junit3/expected.xml

+<dataset>
+	<users id="1" name="Ichiro" />
+	<users id="2" name="Jiro" />
+</dataset>

database-test/src/test/resources/databasetest_junit3/fixtures.xml

+<dataset>
+	<users id="1" name="Ichiro" />
+	<users id="2" name="Jiro" />
+</dataset>
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.