我正在与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)
}
}
}
答案 0 :(得分:0)
好吧,首先GroovySpy
或GroovyStub
对于Java或Kotlin类没有意义,因为Groovy模拟的特殊功能仅适用于Groovy类。因此,如果这是使用的原因,请不要期望能够以这种方式模拟构造函数或静态方法。 here中也有记录:
什么时候应该比常规的模仿更喜欢Groovy的模仿?当使用Groovy 编写规范下的代码时,应使用Groovy模仿,并且需要某些独特的Groovy模仿功能。当从Java代码调用时,Groovy模拟将表现得像常规模拟一样。请注意,仅因为规范和/或模拟类型下的代码是用Groovy编写的,所以不必使用Groovy模拟。除非您有具体的理由使用Groovy模拟,否则请选择常规模拟。
关于间谍的问题,您不能在接口类型上使用间谍。记录在here中:
间谍总是基于真实对象。因此,您必须提供一个类类型而不是接口类型,以及该类型的任何构造函数参数。
因此,要么只是切换到Mock或Stub,它们都适用于接口类型,要么监视实现类。无论如何,我的主要建议是先阅读文档,然后尝试使用Spock这样的新工具。我的印象是您以前没有使用过Spock,但我当然会错了。