HIRO Tracks

山根正大です。Fintech業界エンジニアが日々学んだ知識を発信します。

【Kotlin】ByteBufferの単体試験で末尾の0Byte部分を無視する

これは何?

  • java.nio.ByteBufferを用いてString生成する処理にて、部品化したクラスの単体テストで困ったことの解決

目次

困りごと

    @Test
    fun hoge() {
        val byteBuffer = ByteBuffer.allocate(5) //Byte範囲割り当て
        byteBuffer.put("あ".toByteArray()) //ByteArray追加
        byteBuffer.flip()
        assertEquals("あ",String(byteBuffer.array())) //これでいけると思ったのだが...
    }

↓を参考に、ByteBuffer->ByteArray->Stringの順で変換すればassertできるのでは?と思って書いたところ、テスト失敗しました。

https://hacknote.jp/archives/4482/

スクリーンショット 2022-08-11 0.18.32.png

あらかじめ配置してるByteBufferのうち、ByteArrayが配置されていない(=ByteArray要素が0)の部分も含めてStringに変換されてしまっているため、Actualの方で欲しいStringの後に不要な文字が変換されてしまっています。

参考までに、下記の記載でByteArrayの内容を出力できます。結果は[-29, -127, -126, 0, 0] となっており、5Byteのうち末尾の2Byteが0になっています。

println(byteBuffer.array().contentToString())

案1 ByteArrayOutputStreamで取り扱う

@Test
fun hoge() {
    val stream = ByteArrayOutputStream()
    stream.write("あ".toByteArray()) //ByteArray追加
    assertEquals("あ",String(stream.toByteArray()))
}

案2 Charsets.decodeを使う

@Test
fun hoge() {
    val byteBuffer = ByteBuffer.allocate(5)
    byteBuffer.put("あ".toByteArray())
    byteBuffer.flip()
    assertEquals("あ",StandardCharsets.UTF_8.decode(byteBuffer).toString())
}

https://java.hotexamples.com/jp/examples/java.nio.charset/StandardCharsets.UTF_8/decode/java-standardcharsets.utf_8-decode-method-examples.html