0

すでにこのテストに多くの時間を費やしていて、それから抜け出す理由を説明することができなかったので、私はあなたの助けを求める以外に選択肢はありません:)

JMockitを使用して自分のJDBC「ラッパー」クラスのいくつかをテストしたところ、行き詰まりました。

これはクラスimテストです:

public class JdbcConnectionProperties {
    private Properties properties = new Properties();
    private String username;
    private String password;
    private String connectionString;

    public JdbcConnectionProperties(String propertiesFilePath) {
        loadProperties(propertiesFilePath);
    }

    public void setProperties() {
        username = properties.getProperty("user");
        password = properties.getProperty("password");

        String connectionType = properties.getProperty("connection_type");
        String serverAddress = properties.getProperty("server_address");
        String port = properties.getProperty("port");
        String sid = properties.getProperty("sid");

        //Create a connection string
        connectionString = "jdbc:oracle:" + connectionType + ":@" + serverAddress + ":" + port + ":" + sid;
    }


    private void loadProperties(String propertiesFilePath) {
        String filePath = Thread.currentThread().getContextClassLoader().getResource(propertiesFilePath).getFile();
        //Load properties from classpath
        try {
            properties.load(new FileInputStream(filePath));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public String getUsername() {
        return username;
    }

    public String getPassword() {
        return password;
    }

    public String getConnectionString() {
        return connectionString;
    }

    public Properties getProperties() {
        return properties;
    }
}

これはテストです:

public class JdbcConnectionPropertiesTest {

    @Test
    public void testSetProperties(
//            @Mocked final Properties properties
    ) throws Exception {

        //Mock loadFilePath method so i dont end up mocking a ton of classes
        new MockUp<JdbcConnectionProperties>() {
            @Mock
            void loadProperties(String propertiesFilePath) {
                //Doing nothing, simple "stub" method
            }
        };

        JdbcConnectionProperties jdbcConnectionProperties = new JdbcConnectionProperties("bla");
//        Deencapsulation.setField(jdbcConnectionProperties, "properties", properties);
//        Mockit.stubOutClass(JdbcConnectionProperties.class, "loadProperties");
        final String username = "username";
        final String password = "password";
        final String connectionType = "thin";
        final String serverAddress = "localhost";
        final String port = "1521";
        final String sid = "orcl";
        String connectionString = "jdbc:oracle:" + connectionType + ":@" + serverAddress + ":" + port + ":" + sid;

        new Expectations() {
            @Mocked
            Properties properties;

            {
                properties.get("user");
                result = username;

                properties.get("password");
                result = password;

                properties.get("connection_type");
                result = connectionType;

                properties.get("server_address");
                result = serverAddress;

                properties.get("port");
                result = port;

                properties.get("sid");
                result = sid;
            }
        };

        jdbcConnectionProperties.setProperties();

        Assert.assertEquals("Incorrect user", username, jdbcConnectionProperties.getUsername());
        Assert.assertEquals("Incorrect password", password, jdbcConnectionProperties.getPassword());
        Assert.assertEquals("Incorrect connection string", connectionString, jdbcConnectionProperties.getConnectionString());
    }
}

いくつかのメモ。Deencapsulationを使用して、モックされたプロパティをオブジェクトに強制的に入れてみました(コードにコメントを残しました)。

@Mockedアノテーションでモックしてみました。

私はstubOutClassでそれをスタブしてみました。

これは私が書いている最初のテストではありませんが、JMockitには比較的新しいものです。私が以前に書いたテストは、私にこのような頭痛を引き起こしたことはありません。私はJMockitで約20〜30のテストを書いたと思いますが、このような問題は一度もありませんでした。

エラーは(言及されたすべてのシナリオで):

java.lang.NullPointerException
    at java.util.Hashtable.get(Hashtable.java:335)
    at jdbc.JdbcConnectionPropertiesTest$2.<init>(JdbcConnectionPropertiesTest.java:49)
    at jdbc.JdbcConnectionPropertiesTest.testSetProperties(JdbcConnectionPropertiesTest.java:44)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:71)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:199)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:62)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)

クラスはとてもシンプルです。テストは非常に簡単なはずです。しかし、どういうわけか、テストはExpectationsブロック(最初のプロパティexpectation)でクラッシュします。私が最初のものにコメントすると、それは次のものにそれを投げ続けます。引数のマッチングのためにany、anyStringを試しました。

私の見方では、JdbcConnectionProperties loadPropertiesをモックして、テストを簡素化できるようにしています。次に、モックされたPropertiesオブジェクトをテストに渡します。

その後...

...動作するはずです。ところで、Exceptionsブロックでこの大きさの例外を見たことがありません。

ありがとうございました。

4

2 に答える 2

2

Hashtable#getは、モックされたときにJDKまたはJMockit自体に干渉する可能性があるため、デフォルトではJMockitによってモックされない数少ないメソッドの1つです。この特定のテストを機能させるには、を使用して、モックを明示的に要求し@Mocked("get")ます。

ただし、モックを使用せずに、テストで実際の「.properties」ファイルを使用する方が簡単な場合があります。

于 2011-09-27T21:24:26.550 に答える
0
new Expectations() {
            @Mocked("getProperty")
            Properties properties;

            {
                properties.getProperty("user");
                result = username;

                properties.getProperty("password");
                result = password;

                properties.getProperty("connection_type");
                result = connectionType;

                properties.getProperty("server_address");
                result = serverAddress;

                properties.getProperty("port");
                result = port;

                properties.getProperty("sid");
                result = sid;
            }
        };

Rogerioに感謝します。彼が指摘したように、その理由は「内部」クラスのモックです。覚えておくべき非常に小さな制限。

注意が必要な他のクラスは次のとおりです(私はこれを書くことができるといいのですが):

JMockitでモックするときに覚えておくべきクラス

于 2011-09-28T07:01:28.473 に答える