2017年1月11日水曜日

[JMockit]特定のテストでだけモックを定義する

JMockitで特定のテストでモックを使う方法

使用バージョン

    
      org.jmockit
      jmockit
      1.30
      test
    

サンプルコード

この例では、initialCapacityを受け取るコンストラクタとaddメソッドにモック実装を定義しています。
new MockUp<ArrayList<String>>() {
    @Mock void $init(int initialCapacity) {
        System.out.println("initialCapacity = " + initialCapacity);
    }
    
    @Mock boolean add(String s) {
        System.out.println("s = " + s);
        return true;
    }
};
final List<String> strings = new ArrayList<>(10);
strings.add("hoge");

実行結果

initialCapacity = 10
s = hoge

2016年12月19日月曜日

[H2]ロックタイムアウト時間の変更

ロックタイムアウトのデフォルトは、1000ミリ秒(1秒)となっています。
この値を変更するには、SET LOCK_TIMEOUTを使う。

接続時に値を変更する場合は、下のようにURLの後にLOCK_TIMEOUTを指定する。

jdbc:h2:test;LOCK_TIMEOUT=10000

2016年11月3日木曜日

[Jackson]jsonをMapとして読み込んだ際の数値型を変更する

jsonをMapとして読み込んだ時のデフォルトのデータ型を変更する方法。

読み込むjson

{
  "number": 123456789012,
  "decimal": 1.1
}

デフォルトの設定で読み込んだ結果

こんな結果になる。整数の場合は、読み込む内容によってIntegerに変わったりします。
result = {number=123456789012, decimal=1.1}
number = java.lang.Long
decimal = java.lang.Double

データ型を変更する

下のようにUSE_BIG_INTEGER_FOR_INTSとUSE_BIG_DECIMAL_FOR_FLOATSを有効にします。
objectMapper.enable(DeserializationFeature.USE_BIG_INTEGER_FOR_INTS);
objectMapper.enable(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS);

変更後の読み込んだ結果

result = {number=123456789012, decimal=1.1}
number = java.math.BigInteger
decimal = java.math.BigDecimal

読み込みコードの全体

final ObjectMapper objectMapper = new ObjectMapper();
objectMapper.enable(DeserializationFeature.USE_BIG_INTEGER_FOR_INTS);
objectMapper.enable(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS);

final TypeFactory factory = objectMapper.getTypeFactory();
final Map result =
    objectMapper.readValue(inputStream, factory.constructType(Map.class));
System.out.println("result = " + result);

outputType(result, "number");
outputType(result, "decimal");

2016年10月1日土曜日

[Jackson]Enumの値を読み書きする

Jacksonを使って、json内の値をEnumとして読み書きする方法。

Jacksoのバージョン

compile 'com.fasterxml.jackson.core:jackson-databind:2.8.3'

jsonにマッピングするオブジェクトの定義

json→Enumの変換は@JsonCreatorアノテーションを設定したstaticメソッドで行う。
Enum→jsonの変換は@JsonValueアノテーションを設定したメソッドで行う。
public class SampleBean {

    private Enum value;

    public Enum getValue() {
        return value;
    }

    public void setValue(final Enum value) {
        this.value = value;
    }
}

enum Enum {
    A(1),
    B(2),
    C(3),;

    private int value;

    Enum(final int value) {
        this.value = value;
    }

    @JsonValue
    public int toValue() {
        return value;
    }

    @JsonCreator
    public static Enum fromValue(int value) {
        return Arrays.stream(values())
              .filter(v -> v.value == value)
              .findFirst()
              .orElseThrow(() -> new IllegalArgumentException(String.valueOf(value)));
    }
}

jsonの内容

{"value": 2}

json→Beanに実装

final ObjectMapper objectMapper = new ObjectMapper();

final SampleBean bean = objectMapper.readValue("{\"value\": 2}", SampleBean.class);
System.out.println("bean.getValue() = " + bean.getValue());

final String json = objectMapper.writeValueAsString(bean);
System.out.println("json = " + json);

結果

bean.getValue() = B
json = {"value":2}

2016年8月25日木曜日

[Jackson]デシリアライズ時に発生するUnrecognizedPropertyExceptionを抑止する

Jacksonを使って、jsonをBeanにデシリアライズするときに、jsonには存在しているけどBeanに存在しない属性があるとUnrecognizedPropertyExceptionが発生する。
これを、Jacksonに対する設定で、一括で無効にする方法。

Jacksonのバージョン
compile 'com.fasterxml.jackson.core:jackson-databind:2.8.1'

入力のjson
{"name": "あいうえお"}

beanの定義
class Sample {

    private String name;

    private int age;

    @Override
    public String toString() {
        return "Sample{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

Jacksonを使ったデシリアライズ処理
jsonにだけ存在する属性があった場合に例外を発生させる設定を無効化する設定を行う。
無効化する設定はDeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES。
final ObjectMapper mapper = new ObjectMapper();

// beanに存在しない属性があっても無視する(例外を発生させない)
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);

final String content = "{\"name\": \"あいうえお\"}";
final Sample sample = mapper.readValue(content, Sample.class);

System.out.println("sample = " + sample);


結果
sample = Sample{name='null', age=0}

2016年7月20日水曜日

[JMockit]バージョン1.23からはNonStrictExpectationsではなくExpectationsを使う

バージョン1.23で非推奨になって、1.25で完全に削除されたようです。

JMockitの新しいバージョンを使う場合は、NonStrictExpectationsを使うのではなく、Expectationsを使います。


例

モックが返す値を設定する際にminTimesを使って、最小の呼び出し回数に0を設定する。
これで、NonStrictExpectationsと同じような動きを実現できるようになる。
        new Expectations() {{
            mockList.add("hoge");
            minTimes = 0;

            mockList.get(0);
            result = "1"; minTimes = 0;
        }};

2016年7月19日火曜日

[JMockit]VerificationsでMatcherを使って、モックに渡された値をアサートする

JMockitでモックオブジェクトのメソッドに渡されたオブジェクトをアサートしたい場合は、withArgThatを使う。

使い方

検証したいメソッドの呼び出しに対して、withArgThatを使用して、検証用のwithArgThatを指定する。

この例の場合は、単純にmockList.add("hoge")で置き換えできるが・・・
引数をキャプチャするwithCaptureを使ってたけど、こっちのほうが便利。

    @Mocked
    private List mockList;

    @Test
    public void sample() throws Exception {
        mockList.add("hoge");

        new Verifications() {{
            mockList.add(withArgThat(is("hoge")));
        }};
    }