Тестовый сервис с зависимостями в споке - PullRequest
0 голосов
/ 08 декабря 2018

Я работаю с проектом kotlin и spring, сейчас я пытаюсь выполнить тест некоторого сервиса, у которого есть некоторые зависимости, у меня есть некоторые проблемы, чтобы пройти тест успеха.Возможно, мой дизайн недостаточно хорош, более того, у меня возникают проблемы при попытке вызвать метод из объекта-шпиона, возникает проблема: не удается вызвать реальный метод getClubhouseFor для ложного объекта на основе интерфейса.Это мой код, не могли бы вы дать мне представление о том, что я делаю плохо.

Заранее спасибо !!!!Это мой код:

import com.espn.csemobile.espnapp.models.UID
import com.espn.csemobile.espnapp.models.clubhouse.*
import com.espn.csemobile.espnapp.services.clubhouse.AutomatedClubhouseService
import com.espn.csemobile.espnapp.services.clubhouse.ClubhouseService
import com.espn.csemobile.espnapp.services.clubhouse.StaticClubhouseService
import com.espn.csemobile.espnapp.services.clubhouse.contexts.ClubhouseContext
import com.espn.csemobile.espnapp.services.core.CoreService
import rx.Single
import spock.lang.Specification

class ClubhouseServiceImplTest extends Specification {


    StaticClubhouseService staticClubhouseService = GroovyStub()
    AutomatedClubhouseService automatedClubhouseService = GroovyStub()
    CoreService coreService =  GroovyStub()
    ClubhouseContext clubhouseContext = GroovyMock()
    Clubhouse clubHouse
    ClubhouseLogo clubhouseLogo
    ClubhouseService spy = GroovySpy(ClubhouseService)

    void setup() {
        clubhouseLogo = new ClubhouseLogo("http://www.google.com", true)
        clubHouse = new Clubhouse(new UID(), "summaryType", ClubhouseType.League, new ClubhouseLayout(), "summaryName", "MLB", clubhouseLogo, "http://www.google.com", "liveSportProp",new ArrayList<Integer>(), new ArrayList<ClubhouseSection>(),new ArrayList<ClubhouseAction>(), new HashMap<String, String>())
    }



    def "GetClubhouseFor"() {
        given:
        staticClubhouseService.getClubhouseFor(clubhouseContext) >> buildClubHouseMockService()
        // The idea here is to get different responses it depends on the class of call.
        automatedClubhouseService.getClubhouseFor(clubhouseContext ) >> buildClubHouseMockService()
        spy.getClubhouseFor(clubhouseContext) >> spy.getClubhouseFor(clubhouseContext)
        when:
        def actual = spy.getClubhouseFor(clubhouseContext)
        then:
        actual != null
    }

    def buildClubHouseMockService(){
        return Single.just(clubHouse)
    }
}

Следующие классы участвуют в тесте:

import com.espn.csemobile.espnapp.models.clubhouse.*
import com.espn.csemobile.espnapp.services.clubhouse.contexts.ClubhouseContext
import com.espn.csemobile.espnapp.services.core.CoreService
import org.springframework.context.annotation.Primary
import org.springframework.context.annotation.ScopedProxyMode
import org.springframework.stereotype.Service
import org.springframework.web.context.annotation.RequestScope
import rx.Single

interface ClubhouseService {
    fun getClubhouseFor(context: ClubhouseContext): Single<Clubhouse?>
}

@Service
@RequestScope(proxyMode = ScopedProxyMode.NO)
@Primary
class ClubhouseServiceImpl(private val clubhouseContext: ClubhouseContext,
                        private var staticClubhouseService: StaticClubhouseService,
                       private var automatedClubhouseService: AutomatedClubhouseService,
                       private val coreService: CoreService?): ClubhouseService {

    override fun getClubhouseFor(context: ClubhouseContext): Single<Clubhouse?> {
        return staticClubhouseService.getClubhouseFor(clubhouseContext).flatMap { clubhouse ->
            if (clubhouse != null) return@flatMap Single.just(clubhouse)

            return@flatMap automatedClubhouseService.getClubhouseFor(clubhouseContext)
        }
    }
}

1 Ответ

0 голосов
/ 23 декабря 2018

Ну, во-первых, GroovySpy или GroovyStub не имеют смысла для классов Java или Kotlin, потому что специальные функции имитаций Groovy доступны только для классов Groovy.Так что не ожидайте, что сможете так же насмехаться над конструкторами или статическими методами, если это было причиной использования.Это также задокументировано здесь :

Когда следует использовать Groovy Mocks вместо обычных Mock?Groovy mock следует использовать, когда указанный код написан на Groovy и , поэтому необходимы некоторые уникальные функции Groovy mock.При вызове из кода Java Groovy mocks будет вести себя как обычные mock.Обратите внимание, что нет необходимости использовать макет Groovy только потому, что специфицированный код и / или макетный тип написан на Groovy.Если у вас нет конкретной причины использовать макет Groovy, предпочтите обычный макет.

Что касается вашей проблемы со шпионом, вы не можете использовать шпиона в типе интерфейса.Это задокументировано здесь :

Шпион всегда основан на реальном объекте.Следовательно, вы должны предоставить тип класса, а не тип интерфейса, наряду с любыми аргументами конструктора для типа.

Так что вы либо просто переключаетесь на Mock или Stub, оба из которых работают на типах интерфейса, либовместо этого вы следите за классом реализации.В любом случае, мое главное предложение - сначала прочитать документацию, а затем попробовать использовать новый инструмент, такой как Spock.У меня сложилось впечатление, что ты раньше не использовал Спока, но, конечно, я могу ошибаться.

...