我正在尝试使用Spock 框架来实现单元测试,这就是我的测试的样子:
def setup() {
scrollableResultsMock = Mock(ScrollableResults)
paymentRepositoryMock = Mock(PaymentRepository)
paymentRegistryService = new PaymentRegistryService(paymentRepositoryMock)
}
@Unroll
def 'should correctly process'() {
given:
paymentRepositoryMock.findUnconfirmedTransactions(_ as LocalDate, _ as Days) >> scrollableResultsMock
...
}
Run Code Online (Sandbox Code Playgroud)
这是我尝试注入模拟对象的类:
@Service
open class PaymentRegistryService
@Autowired
constructor(
val paymentRepository: PaymentRepository
) {
@Transactional
open fun parseRegistryFileStream(input: InputStream): LinkedList<Pair<Long, String>> {
...
val registry = paymentRepository.findUnconfirmedTransactions(start, PERIOD)
...
}
}
Run Code Online (Sandbox Code Playgroud)
在运行测试而不是调用我的方法时,paymentRepository
正在调用真正的方法。我不明白可能是什么原因。LocalDate
来自Joda 时间,最后是课程Days
:paymentRepository
@Repository
@Transactional
open class PaymentRepository …
Run Code Online (Sandbox Code Playgroud) 我正在使用 Groovy+Geb+Spock+Gradle 框架编写自动化测试脚本。我有一个名为“UserProfilePageSpec”的规范来检查用户个人资料页面的 UI,现在我想多次运行它来检查多个用户。我在那里添加了随机性,以便每次规范都会在列表中选择一个随机用户并导航到用户个人资料页面。
另外,我想检查每种用户类型的 5 个用户(这是主页中的过滤器)。所以我需要点击主页中的每个用户类型,然后多次运行规范。
有时,当没有足够的时间来测试每种类型的多个用户时,我只需要测试一个用户,所以我有点想保留这个规范来测试一个用户本身,有人有实现这个的好主意吗?谢谢!
这是“UserProfilePageSpec”的基本结构:
class UserProfilePageSpec {
def setupSpec(){
//login
//select a random user
//navigate to user profile page
}
def "test1"(){..}
def "test2"(){..}
def "test3"(){..}
def "test4"(){..}
}
Run Code Online (Sandbox Code Playgroud) 如何在测试类中mock私有方法和不同类中的方法?
class MyClass {
private final Retriever<ScoreData> retriever;
private DataStore<Model> dataStore;
private String gameName;
public void MyClass(Retriever<ScoreData> retriever, DataStore<Model> dataStore, String gameName) {
this.retriever = retriever;
this.dataStore = dataStore;
this.gameName = gameName;
}
public void process(GameHolder<G> games) {
// Business Logic
for (Game<G> game : games){
Integer score = game.getScore();
Integer playerId = game.getPlayerId();
Integer finalScore = getScore(game);
computeScore(score, finalScore);
}
}
private Integer computeScore(int score, int finalScore) {
// Runs some business logic and returns O3
return score + …
Run Code Online (Sandbox Code Playgroud) 我的应用程序中有一个服务返回一个轨道列表,这里是代码
List<Track> getTrackListTracks(String listName, int max) {
def tracks = getTrackListTracks(listName)
if(tracks?.size() > max) {
tracks = tracks[0 ..< max]
}
return tracks
}
List<Track> getTrackListTracks(String listName) {
def tl = TrackList.findByName(listName)
if(tl?.tracks) {
return tl?.tracks?.collect { Track.read(it.trackId) }
}
}
Run Code Online (Sandbox Code Playgroud)
我必须为此编写单元测试,但我无法写.任何人都可以帮助我.谢谢已经
我有一个像这样的控制器:
@Secured(['ROLE_USER','IS_AUTHENTICATED_FULLY'])
def userprofile(){
def user = User.get(springSecurityService.principal.id)
params.id = user.id
redirect (action : "show", params:params)
}
Run Code Online (Sandbox Code Playgroud)
我想在spock中测试控制器上面的控制器,所以我写了一个像这样的测试代码:
def 'userProfile test'() {
setup:
mockDomain(User,[new User(username:"amtoasd",password:"blahblah")])
when:
controller.userprofile()
then:
response.redirectUrl == "/user/show/1"
}
Run Code Online (Sandbox Code Playgroud)
当我运行我的测试时,此测试失败并显示以下错误消息:
java.lang.NullPointerException: Cannot get property 'principal' on null object
at mnm.schedule.UserController.userprofile(UserController.groovy:33)
Run Code Online (Sandbox Code Playgroud)
在集成测试的情况下:
class UserSpec extends IntegrationSpec {
def springSecurityService
def 'userProfile test'() {
setup:
def userInstance = new User(username:"antoaravinth",password:"secrets").save()
def userInstance2 = new User(username:"antoaravinthas",password:"secrets").save()
def usercontroller = new UserController()
usercontroller.springSecurityService = springSecurityService
when:
usercontroller.userprofile()
then:
response.redirectUrl == "/user/sho" …
Run Code Online (Sandbox Code Playgroud) public boolean accept(File directory, String fileName) {
boolean fileOK = true;
if (name != null) {
fileOK &= fileName.startsWith(name);
}
if (pattern != null) {
fileOK &= Pattern.matches(regex, fileName);
}
if (extension != null) {
fileOK &= fileName.endsWith('.' + extension);
}
return fileOK;
}
Run Code Online (Sandbox Code Playgroud) 我有一个配置了jacoco插件的Gradle项目来报告测试代码的覆盖范围.我的单元测试是用Spock框架编写的.
虽然Jacoco插件生成HTML报告,但它会将所有类的代码覆盖率报告为0%.
我google了很多,找不到我想念的东西.有没有人使用Gradle + Jacoco进行Spock代码覆盖?
apply plugin: "jacoco"
apply plugin: "groovy"
sourceSets {
main {
java { srcDirs = ['src/main/java'] }
groovy {srcDirs = ['src/main/groovy'] }
resources { srcDir 'src/main/resources' }
}
test {
java { srcDirs = ['src/test/java'] }
groovy { srcDirs = ['src/test/groovy'] }
resources { srcDir 'src/test/resources' }
}
}
test {
jvmArgs '-Xms64m', '-Xmx2G', '-XX:MaxPermSize=128m'
}
jacocoTestReport {
reports {
xml.enabled false
csv.enabled false
html.destination "${buildDir}/jacocoHtml"
}
}
dependencies {
testCompile "org.spockframework:spock-core:0.7-groovy-2.0"
testCompile "org.spockframework:spock-spring:0.7-groovy-2.0"
}
Run Code Online (Sandbox Code Playgroud) 我正忙着在Geb/Spock中进行e2e测试,我想知道如何添加自定义消息.现在我只得到这样的堆栈跟踪:
geb.error.RequiredPageContentNotPresent: The required page content 'pages.patientConversation.PcModal -> contact: geb.navigator.EmptyNavigator' is not present
at geb.content.TemplateDerivedPageContent.require(TemplateDerivedPageContent.groovy:60)
at geb.content.PageContentTemplate.create_closure1(PageContentTemplate.groovy:63)
at geb.content.PageContentTemplate.create_closure1(PageContentTemplate.groovy)
Run Code Online (Sandbox Code Playgroud)
等......
这是我测试的一个例子:
def "allow for searching contacts"() {
when:
to LoginPage
login(emailAddress, defaultPassword)
then:
at QuickBar
when:
startButton.click()
then:
at Modal
when:
selectContactButton.click()
contactSearchField.value(context.pcUser2.surname)
then: "the contact is shown in the search results"
contact.isDisplayed()
}
Run Code Online (Sandbox Code Playgroud)
我认为文本"联系人显示在搜索结果中"将出现在错误消息中,但显然它没有.是否可能有另一种方式在Spock的Geb中打印自定义消息以获得更清晰的信息?
特别是对于'跳棋'我想要自定义消息,因为当检查失败时,你只会得到:
java.lang.NoSuchMethodError: geb.error.GebAssertionError.<init>(Ljava/lang/Object;Ljava/lang/Throwable;)V
at geb.waiting.WaitTimeoutException.<init>
Run Code Online (Sandbox Code Playgroud)
等等
编辑:嗯,我现在意识到,测试失败了,因为它还会在执行"then"之前检查所需的页面内容.我仍然希望能够添加自定义消息(特别是'在跳棋')...有人知道这是否可能?
我有很多重复测试,我想以某种方式抽象它们.辅助方法很有用,但最重要的是.如果我能以某种方式在我的程序中生成测试方法,我将能够删除大量的复制粘贴代码Specification
.
具体来说,我正在测试RPC层的方法.如果不以某种方式调用它们,大多数方法必须失败.所以我有Spock测试方法,如:
def observer = Mock(StreamObserver)
def rpc = new UserServiceRpc()
def "draftToOutbox: should fail when called without parent"() {
def request = draftToOutboxRequest().toBuilder().clearParent().build()
when:
rpc.draftToOutbox(request, observer)
then:
1 * observer.onError(_)
1 * observer.onCompleted()
}
def "outboxToDraft: should fail when called without parent"() {
def request = outboxToDraftRequest().toBuilder().clearParent().build()
when:
rpc.outboxToDraft(request, observer)
then:
1 * observer.onError(_)
1 * observer.onCompleted()
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,我不熟悉Groovy的元编程(编译时AST转换)功能,并且不确定如何做到这一点,是否有可能,以及这是否是一个好主意.一方面我有一些复制粘贴,但另一方面我的测试非常易读.不过,我倾向于拥有两全其美:没有复制粘贴的可读性.
完全披露:我对Geb和Spock都很陌生.
作为我正在研究的测试套件的一部分,我们必须测试在几个页面元素上运行相同的测试.我希望能够使用Spock数据表来抽象这种行为.但是,当我这样做时,Geb抱怨它无法识别页面属性.
这是我正在谈论的一个简单的例子:
when:
textBox = value
submit()
then:"value is updated"
at SuccessPage
textBox == value
where:
textBox | value
box1 | val1
box2 | val2
box3 | val3
Run Code Online (Sandbox Code Playgroud)
在此实例中,盒1-3的定义内容一个的对象页面.
这些测试在我独立完成时起作用,但在我使用数据表时则不行.为什么Geb元素没有被正确替换?