Kotlinのリソースからテキストファイルを読み取る方法


94

KotlinでSpekテストを記述したい。テストでは、src/test/resourcesフォルダーからHTMLファイルを読み取る必要があります。どうやってするの?

class MySpec : Spek({

    describe("blah blah") {

        given("blah blah") {

            var fileContent : String = ""

            beforeEachTest {
                // How to read the file file.html in src/test/resources/html
                fileContent = ...  
            }

            it("should blah blah") {
                ...
            }
        }
    }
})

回答:


111
val fileContent = MySpec::class.java.getResource("/html/file.html").readText()

30
私にとってこれはうまくいかなかったので、変更する必要がありましたthis::class.java.classLoader.getResource("/html/file.html").readText()
pavlos163

4
私の両方のために、これらのオプションは、(予告余分をAndroidアプリで働いていた/:他に除去されなければならないそのうちの一つで、)this::class.java.getResource("/html/file.html").readText()this::class.java.classLoader.getResource("html/file.html").‌​readText()
フランコ

19
val fileContent = javaClass.getResource("/html/file.html").readText()仕事はさらに短くなる
フランク・ネブルン

28

別のわずかに異なるソリューション:

@Test
fun basicTest() {
    "/html/file.html".asResource {
        // test on `it` here...
        println(it)
    }

}

fun String.asResource(work: (String) -> Unit) {
    val content = this.javaClass::class.java.getResource(this).readText()
    work(content)
}

拡張機能の素敵な使い方!しかし、なぜここでラムダ関数を使用するのですか?それは私にはあまり意味がありません。さらに、そのthis部分は私にはうまくいきませんでした。したがって、以下をお勧めしますfun String.asResource(): URL? = object {}.javaClass.getResource(this)
。– Qw3ry

私は、ファイルを宣言してそのファイルの内容を処理するこの方法で作業するのが好きです。個人的な好みだと思います。this上記の例では、文字列オブジェクトを参照しています。
jhodges

それは拡張機能のひどい乱用です。ファイルのロードは、Stringクラスの問題ではありません。
ベン

それはこの文脈にあります。これをグローバルに利用可能にしたり、テストクラスの外で使用したりすることはありません。ここでは、それをマッピング関数と考えます。
jhodges

26

これがそれほど難しい理由はわかりませんが、(特定のクラスを参照する必要がない)私が見つけた最も簡単な方法は次のとおりです。

fun getResourceAsText(path: String): String {
    return object {}.javaClass.getResource(path).readText()
}

次に、絶対URLを渡します。

val html = getResourceAsText("/www/index.html")

される{}必要?なぜjavaClass.getResource(path).readText()ですか?
andrewgazelka

1
ドキュメントに従って、javaClassをオブジェクトで呼び出す必要がありますkotlinlang.org/api/latest/jvm/stdlib/kotlin.jvm/java-class.html それが機能しない場合は、次のライフを続けてください:)
Russell Briggs

3
上記のメソッドの1つの欠点は、すべてのリソースアクセスに対して新しいオブジェクトが作成されることです。関数の外にダミーオブジェクトを保存する方が良いでしょう。
ラッセルブリッグズ

@RussellBriggs tbh私はそれはそれほど重要ではないと思います。ディスクアクセスを行う場合、オブジェクト作成のパフォーマンスは実際には問題になりません。
Qw3ry

13

少し異なる解決策:

class MySpec : Spek({
    describe("blah blah") {
        given("blah blah") {

            var fileContent = ""

            beforeEachTest {
                html = this.javaClass.getResource("/html/file.html").readText()
            }

            it("should blah blah") {
                ...
            }
        }
    }
})

どういうわけか、これは私にはうまくいきませんでした。クラスを明示的に呼び出すだけで機能しました。他の人のために追加するだけです。tornadofxと関係があると思います
nmu

テスト入力ファイルを作成した後/src/test/resourcesthis.javaClass.getResource("/<test input filename>")予想通りに働いていました。上記の解決策をありがとう。
jkwuc89

fileContentがStringではなく、ダミーオブジェクトを作成しない場合の対処方法
minizibi 2018

1
パスの前のスラッシュはここでは必須のようですが、Javaでは通常省略します。
cakraww 2018


5

Kotlin + Spring way:

@Autowired
private lateinit var resourceLoader: ResourceLoader

fun load() {
    val html = resourceLoader.getResource("classpath:html/file.html").file
        .readText(charset = Charsets.UTF_8)
}

5
private fun loadResource(file: String) = {}::class.java.getResource(file).readText()

4

Google Guavaライブラリのリソースクラスを使用:

import com.google.common.io.Resources;

val fileContent: String = Resources.getResource("/html/file.html").readText()

リソースが見つからない場合、Guaveがファイル名を報告するのは素晴らしいことです。トラブルシューティングにははるかに優れています
Nishi

0

Fileクラスが便利な場合があります。

import java.io.File

fun main(args: Array<String>) {
  val content = File("src/main/resources/input.txt").readText()
  print(content)
} 

3
この答えは誤解を招くものです。これは「リソース」をロードしませんが、クラスパスの代わりにファイルシステムから直接ファイルをロードします。jarファイルからロードするのではなく、存在しないファイルを参照しようとするため、アプリケーションのアセンブル後は機能しなくなります。
ベン

@benコメントありがとうございます。質問は、kotlin Spekテストでリソースからファイルを読み取ることに関するものでした。
Krzysztof Ziomek

0

これは私がそれを好む方法です:

fun getResourceText(path: String): String {
    return File(ClassLoader.getSystemResource(path).file).readText()
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.