2015-05-25 19 views
7

Czy można używać funkcji pakietu Kotlin i właściwości pakietu w różnych zestawach źródłowych? Kiedy próbuję to zrobić, wyrzucam NoSuchMethodError.Kotlin: java.lang.NoSuchMethodError w testach


Przykład

mam projekt Gradle z kodem Kotlin i dwa sourcesets w nim, main i test. W main, Mam następujący kod w jednym z plików:

package ru.ifmo.ctddev.igushkin.dkvs 
... 
public val payloadSplitter: String = " ### " 

W test próbie uzyskania dostępu payloadSplitter z następującego kodu:

package ru.ifmo.ctddev.igushkin.dkvs 
... 
public class MessageTests { 
    ... 
    test fun testParsing() { 
     ... 
     checkParseAndToString("p1b 345 ${payloadSplitter} set a b c") 
    } 
    ... 
} 

I dokładnie w pierwszej linii, gdzie payloadSplitter jest dostępne, w czasie wykonywania otrzymuję

java.lang.NoSuchMethodError: ru.ifmo.ctddev.igushkin.dkvs.DkvsPackage.getPayloadSplitter()Ljava/lang/String; 

Inne zmienne globalne i funkcje są również niedostępne w test z tym samym błędem.


UPD zespół Kotlin wyjaśnił tę kwestię i zapowiedział poprawkę here.

+1

Czy masz jakieś funkcje/właściwości najwyższego poziomu w pakiecie ru.ifmo.ctddev.igushkin.dkvs w testach? –

+0

Jak uruchomić testy? Czy mógłbyś opublikować swoją konfigurację gradle? Wygląda na to, że pakiet testowy jest skompilowany z pakietem głównym, ale działa bez niego. –

+0

@SalomonBRYS, https://github.com/h0tk3y/dkvs/blob/master/build.gradle - oto on. – hotkey

Odpowiedz

5

Dla właściwości i metod poza klasami, Kotlin tworzy klasę java o nazwie $ {nazwa-pakietu} Pakiet z właściwościami i metodami zaimplementowanymi jako statyczne metody i zmienne. W przypadku wielu zestawów źródłowych klasa java zostanie utworzona dwukrotnie, raz dla każdego zestawu źródeł. Twoim problemem jest to, że zestaw źródeł testu "klasa pakietów" ukrywa klasę skompilowaną w głównym zestawie źródłowym.

Jak wspomniano w komentarzach powyżej, należy unikać jakichkolwiek właściwości lub metod najwyższego poziomu w zestawie źródeł testu, aby uniemożliwić kompilatorowi Kotlin tworzenie tej klasy pakietu w katalogu wyjściowym testu.

+0

Dzięki. Jest jeszcze jedno obejście, które wynika z tego, co powiedziałeś, napisałem to jako kolejną odpowiedź. – hotkey

+0

Kolejna uwaga dodatkowa do tego rozwiązania; przynajmniej w Gradle, musisz uruchomić czystą kompilację, lub biegacz testu nadal znajdzie wygenerowaną klasę Package. –

1

Oprócz tego, co zasugerowano wcześniej, znalazłem inne obejście: jeśli potrzebujesz funkcji lub właściwości na poziomie pakietu w test, przenieś testy do innej paczki, np. w swoich źródeł Test:

package ru.ifmo.ctddev.igushkin.dkvs.tests 

a następnie wykonaj

import ru.ifmo.ctddev.igushkin.dkvs.* 

który wszystko z głównego pakietu. To sprawi, że Kotlinowy kompilator wygeneruje dwie niekompatybilne klasy pakietów, dlatego oba mogą mieć członków globalnych.

Powiązane problemy