我正在处理一个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)
}
}
}发布于 2018-12-23 02:08:53
首先,GroovySpy或GroovyStub对Java或Kotlin类没有意义,因为Groovy模拟的特殊特性仅适用于Groovy类。因此,如果使用这种方法的原因是这样的话,不要指望能够以这种方式模拟构造函数或静态方法。这也是文档化的这里。
什么时候Groovy Mocks应该比普通Mocks更受欢迎?在用Groovy编写规范下的代码时,应该使用Groovy模拟,并且需要一些独特的Groovy模拟特性。当从Java代码调用时,Groovy模拟的行为将像普通的模拟一样。请注意,仅仅因为规范和/或模拟类型下的代码是用Groovy编写的,就没有必要使用Groovy模拟。除非您有具体的理由使用Groovy模拟,否则更喜欢常规的模拟。
至于间谍的问题,您不能在接口类型上使用间谍。这是记录在案的这里
间谍总是以一个真实的对象为基础。因此,您必须提供类类型,而不是接口类型,以及该类型的任何构造函数参数。
所以,要么切换到Mock或Stub,它们都可以处理接口类型,要么监视实现类。无论如何,我的主要建议是先阅读文档,然后尝试使用像Spock这样的新工具。我的印象是,你以前没有使用过斯波克,但当然我可能错了。
https://stackoverflow.com/questions/53677397
复制相似问题