190 votes

Comment lire un fichier texte à partir de ressources en Kotlin ?

Je veux écrire un test Spek en Kotlin. Le test doit lire un fichier HTML à partir de la page src/test/resources dossier. Comment faire ?

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") {
                ...
            }
        }
    }
})

211voto

JB Nizet Points 250258
val fileContent = MySpec::class.java.getResource("/html/file.html").readText()

61 votes

Pour moi, cela n'a pas fonctionné, j'ai dû le changer en this::class.java.classLoader.getResource("/html/file.html").‌​readText()

6 votes

Pour moi, ces deux options ont fonctionné dans une application Android (remarquez l'ajout de l'option / dans l'un d'eux, qui doit être retiré dans l'autre) : this::class.java.getResource("/html/file.html").readText() y this::class.java.classLoader.getResource("html/file.html").‌​readText()

44 votes

val fileContent = javaClass.getResource("/html/file.html").readText() fait le travail encore plus rapidement

85voto

Russell Briggs Points 126

Je ne sais pas pourquoi c'est si difficile, mais la méthode la plus simple que j'ai trouvée (sans avoir à faire référence à une classe particulière) est la suivante :

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

Et ensuite passer dans une URL absolue, par exemple.

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

2 votes

Est {} nécessaire ? Pourquoi ne pas simplement javaClass.getResource(path).readText() ?

3 votes

JavaClass doit être appelé sur un objet selon la documentation kotlinlang.org/api/latest/jvm/stdlib/kotlin.jvm/java-class.html Si cela fonctionne sans, alors allez-y :)

4 votes

Un inconvénient de la méthode ci-dessus est qu'elle crée un nouvel objet pour chaque accès aux ressources. Il serait préférable de stocker l'objet factice en dehors de la fonction.

32voto

jhodges Points 203

une autre solution légèrement différente :

@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)
}

0 votes

Belle utilisation d'une fonction d'extension ! Mais pourquoi utilisez-vous une fonction lambda ici ? Cela n'a pas beaucoup de sens pour moi. De plus, le this Cette partie n'a pas fonctionné pour moi. Je recommande donc ce qui suit : fun String.asResource(): URL? = object {}.javaClass.getResource(this)

0 votes

J'aime cette méthode de travail où l'on déclare le fichier, puis on travaille sur le contenu de ce fichier. Une préférence personnelle, je suppose. this dans l'exemple ci-dessus fait référence à l'objet chaîne de caractères.

28 votes

C'est un terrible abus de la fonction d'extension. Le chargement des fichiers n'est pas une préoccupation de la classe String.

19voto

Olaf Points 115

Une solution légèrement différente :

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

            var fileContent = ""

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

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

0 votes

Pour une raison quelconque, cela n'a pas fonctionné pour moi. Seul l'appel explicite de la classe a fonctionné. J'ajoute juste pour les autres. Je pense que cela a quelque chose à voir avec tornadofx.

2 votes

Après avoir créé un fichier d'entrée de test dans /src/test/resources , this.javaClass.getResource("/<test input filename>") a fonctionné comme prévu. Merci pour la solution ci-dessus.

0 votes

Que faire, si fileContent n'est pas String et que je ne veux pas créer d'objet factice ?

11voto

jivimberg Points 366
val fileContent = javaClass.getResource("/html/file.html").readText()

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X