Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • 20:21
    szpak commented #1309
  • 15:23
    leonard84 synchronize #1320
  • 15:15
    leonard84 review_requested #1320
  • 15:15
    leonard84 review_requested #1320
  • 15:15
    leonard84 opened #1320
  • May 07 01:13
    jacattau commented #1288
  • May 02 14:08

    github-actions[bot] on gh-pages

    Publish docs/2.0-SNAPSHOT (compare)

  • May 02 14:07

    github-actions[bot] on gh-pages

    Publish javadoc/2.0-SNAPSHOT (compare)

  • May 02 14:01

    leonard84 on groovy-3.0.8

    (compare)

  • May 02 14:01

    leonard84 on master

    Upgrade groovy to 3.0.8 and som… (compare)

  • May 02 14:01
    leonard84 closed #1316
  • May 02 13:57
    codecov[bot] commented #1316
  • May 02 13:57
    codecov[bot] commented #1316
  • May 02 13:57
    codecov[bot] commented #1316
  • May 02 13:56
    codecov[bot] commented #1316
  • May 02 13:53
    codecov[bot] commented #1316
  • May 02 13:53
    codecov[bot] commented #1316
  • May 02 13:53
    codecov[bot] commented #1316
  • May 02 13:53
    codecov[bot] commented #1316
  • May 02 13:52
    codecov[bot] commented #1316
Björn Lindahl
@blindahl
Absolutely, every idea is welcome at this point :)
Leonard Brünings
@leonard84
None of the parallel extensions have any effect if spock isn't running in parallel mode
All they do is set meta data, that is used by the JUnit Platform and in the non parallel mode that meta data is ignored
Björn Lindahl
@blindahl
I have three config files right now, one for each module in our project but I only added them to add runner.parallel.enabled=false. Right now I added a println to them as well which was printed when running locally. Will try on CI as well.
Alexander Kriegisch
@kriegaex
Do you have any parallel configuration e.g. for Maven builds in general, Maven Surefire in particular or the Gradle equivalents, something independent of Spock? (Maybe a desperate guess and I am not even sure how this would work in combination with Spock 2.)
Leonard Brünings
@leonard84
runner.parallel.enabled=false is the default you need to opt-in to parallel execution with runner.parallel.enabled=true
Alexander Kriegisch
@kriegaex

Exactly! That's what I meant when I said earlier:

IMO if you run Spock without explicitly enabling parallel execution and believe to have concurrency issues, logic implies that (...)

Leonard Brünings
@leonard84

btw spocks config scrips are groovy so you can do stuff like

runner {
    parallel {
        enabled !System.getenv('CI')
    }
}

Instead of having 3 different files

Björn Lindahl
@blindahl
Hmm, have to check how maven surefire build
Ah ok, can use one config file then that way.
We didn't think it was running in parallel either but we wanted to set it explicitely.
Leonard Brünings
@leonard84
Also be aware that Surefire has some issues with the JUnit Platform
Björn Kautler
@Vampire
This friday Gr8 tech talk with Leonard about cool new things in Spock 2.0: https://twitter.com/gr8conf/status/1351127175286706177
sevenlist
@sevenlist

Hello! Using Spock, I try to use Mockito's static mocking feature. Here's a simple example for mocking an SLF4J/Logback Logger:

given:
Logger loggerMock = Mock()
MockedStatic loggerFactoryMockitoMock = Mockito.mockStatic(LoggerFactory)
loggerFactoryMockitoMock.when(LoggerFactory.getLogger(ClassThatLogs)).thenReturn(loggerMock)

and:
def objectThatLogs = new ClassThatLogs()

when:
objectThatLogs.logSomethingWithInfo()

then:
1 * loggerMock.info('some expected message')

cleanup:
loggerFactoryMockitoMock.close()

This works, but not with @Unroll tests, because from the second test on the class ClassThatLogs still references the loggerMock from the first test. To me it looks like as if the class ClassThatLogs has not been reloaded. Do you how I could make it work?

(BTW: ClassThatLogs has a private static final Logger LOG = LoggerFactory.getLogger(ClassThatLogs.class);)

4 replies
Leonard Brünings
@leonard84
Well, as the field is private static final it will only get initialized once.
sevenlist
@sevenlist
Thanks @leonard84, so it means that ClassThatLogs is not reloaded for @Unrolled tests? I thought/was hoping there might be a Spock configuration/annotation for selecting the class loading strategy ;). But I guess my use case is too esoteric.
2 replies
Leonard Brünings
@leonard84
For your case it might be the easiest to stick with a mockito mock for the logger also, and put that in a @Shared field, but keep in mind that other tests for this class could also initialize it earlier and thus mess it up.
6 replies
if you really have need of testing the logging you could try https://projects.lidalia.org.uk/slf4j-test/
8 replies
Alexander Kriegisch
@kriegaex
Another alternative would be to implement the Logger interface and provide a delegating logger, something similar to LoggerWrapper, but with a non-final delegate and a setter for updating it. Then in each iteration you could set the new Spock mock as a delegate and then verify interactions on it without using detached mocks or shared fields. Sometimes doing a little bit of development work for a custom mock is better than pulling new dependencies into your project just for testing one thing. The mockStatic would return the delegating wrapper, of course.
16 replies
A good IDE like IntelliJ IDEA can automatically create all methods necessary for a delegate. Or maybe a Groovy @Delegate would be even better, I didn't really think it through and/or try. In my time zone I am about to start dinner. But it would be interesting to try later.
Leonard Brünings
@leonard84

@sevenlist Maybe just refactor your ClassThatLogs into

class ClassThatLogs {
    private static final Logger LOG_INSTANCE = LoggerFactory.getLogger(ClassThatLogs.class);

    private final Logger log;

    ClassThatLogs() {
        log = LOG_INSTANCE;
    }

    ClassThatLogs(Logger logger) {
        log = logger;
    }
}

And just use the constructor to inject your mocked logger and just use log instead of LOG_INSTANCE in the class.
If you don't want to expose it in the constructor you could also use groovys ability to access private fields.

class ClassThatLogs {
    private static final Logger LOG_INSTANCE = LoggerFactory.getLogger(ClassThatLogs.class);

    private Logger log = LOG_INSTANCE;
}

To modify the log field from the spec.

IMHO this is much a much cleaner approach then the other variants.

Alexander Kriegisch
@kriegaex
Static fields are always difficult to test, but it is kind of a standard pattern for loggers. Some people might not even use it (the pattern) intentionally, adding loggers via Lombok or Groovy transformations. Either way, adding an additional non-static logger field just for injectability from tests, while working nicely of course, looks super ugly IMO - especially if you have to do it in many classes. I think the perfect solution does not exist, like I just said in the other thread about my own too.
3 replies
Configuring the log framework to use a testable logger (like Björn said) is surely the cleanest way with regard to not having to use any dirty tricks or extend the application code just for tests, but of course then the tests are more like integration tests with regard to the log framework not being "mocked away".
r-asou
@r-asou:matrix.org
[m]
hi guys, when I used Spock with SpringBoot to do Unit Test for Service layer. I got this error you need to use @ContextConfiguration or @SpringBootTest(classes=...) with your test
But when I saw some example online, they didn't do any special settings
Alexander Kriegisch
@kriegaex
It would be helpful to share an MCVE, at least a full Spock specification (test class).
Björn Kautler
@Vampire
Björn Kautler
@Vampire

https://twitter.com/spockframework/status/1377558567130107906

We have been advised of a copyright issue with the Spock name, to avoid future problems in this regard we have decided to rebrand. Henceforth, the Spock Framework will be renamed to GWT Framework (Given-When-Then).
Read the full announcement here https://spockframework.org/rebrand-announcement.html

spartanhooah
@spartanhooah

I'm taking a class on Reactive Spring, and I've been able to use Spock no problem so far, but now there's a test using StepVerifier.withVirtualTime() and it passes no matter what. Here's the whole test:

def "With virtual time"() {
    given:
    VirtualTimeScheduler.getOrSet()
    def longFlux = Flux.interval(Duration.ofSeconds(1))
        .take(3)
        .log()

    expect:
    StepVerifier.withVirtualTime({ longFlux.log() })
        .expectSubscription()
        .thenAwait(Duration.ofSeconds(3))
        .expectNext(0L, 1L, 2L)
        .verifyComplete()
}

I also don't see the logs from the flux. Any ideas?

Leonard Brünings
@leonard84
IIRC you need to create the flux inside the withVirtualTime method, see https://www.baeldung.com/reactive-streams-step-verifier-test-publisher#3-testing-time-based-publishers as an example. Also you don't need VirtualTimeScheduler.getOrSet()AFAIK.
spartanhooah
@spartanhooah
That's true, don't need VirtualTimeScheduler.getOrSet(), thanks.
kwangomango
@kwangomango
Is it possible to put Spock conditions in an external helper class and still get Spock to raise ConditionNotSatisfiedException? Any asserts i have in external helper methods just get treated like regular Groovy asserts.
class Testy extends Specification {

    Helper helper = new Helper()

    void "testy"() {

        expect:
           verify()
           helper.verify()

    }


    void verify() {  
        assert 1 == 2
    }
}

class Helper {

    void verify() {
        assert 1 == 3
    }
}
Leonard Brünings
@leonard84
No it is not possible, Spock only transforms classes derived from Specification. You might have a pseudo-Specification without any actual tests and only helper methods though.
kwangomango
@kwangomango
Thanks Leonard, so you are saying to have my Helper class extend Specification too? I see that works.
Leonard Brünings
@leonard84
yes
kwangomango
@kwangomango
:thumbsup:
Leonard Brünings
@leonard84
You can't have external mock interactions though
kwangomango
@kwangomango
That's fine, i'm mostly using Spock for integration tests on apis.
If i make the external helper a closure, rather than a method, then it works just like a local method on Specification. Why is that?
class ClosureTest extends Specification {

    Helper helper = new Helper()

    void "testy"() {

        expect:
            verify.call()
    }

}

class Helper {

    Closure verify= { assert 1 == 2 }

}
Vahid Pazirandeh
@vahidpaz
What http client normally blends well with Spock website functional testing? I've looked at a few (httpbuilder, httpbuilder-ng) and I like their syntax (httpbuilder is nice) bit those projects are either abandoned or dormant. I'd like to use something actively support. thx
Leonard Brünings
@leonard84
you could use https://rest-assured.io/ although it has its own when-then methods
Vahid Pazirandeh
@vahidpaz
Yes I noticed it does. It looks to be an all-inclusive library, even allowing groovy syntax in strings (I guess that it eval()'s on). I'll play around and see if there's a happy middle-ground
Vahid Pazirandeh
@vahidpaz
@leonard84 - thank you for all the time/effort you put in for Spock. It's a real blessing for people around the world.
Leonard Brünings
@leonard84
thanks
Björn Kautler
@Vampire
@vahidpaz I heard and read very good things about Geb and it is nicely integrated with Spock too.
Leonard Brünings
@leonard84
Geb is for browser testing, I assumed the question was geared towards REST API testing
Björn Kautler
@Vampire
Which part of "website functional testing" makes you think so?
"i'm mostly using Spock for integration tests on apis" was a different user one message earlier
Leonard Brünings
@leonard84
Well, since the listed frameworks where http clients and not selenium/webdriver, I assumed testing should be done on the http/rest layer.
If you want browser tests, then sure Geb is the best choice for Spock.
Vahid Pazirandeh
@vahidpaz
@Vampire thank you for the info. Yes I was referring to rest api testing but when the time comes to sprinkle some web app UI testing (some call it user acceptance tests?) I will take a look at Geb. thx again