Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • 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
  • May 02 13:52
    codecov[bot] commented #1316
  • May 02 13:52
    codecov[bot] commented #1316
  • May 02 13:47
    codecov[bot] commented #1316
  • May 02 13:47
    leonard84 synchronize #1316
  • May 02 13:47

    leonard84 on groovy-3.0.8

    Fix implicit this conversion af… Merge branch 'master' into szpa… (compare)

  • May 02 13:46

    leonard84 on master

    Fix implicit this conversion af… (compare)

Alexander Kriegisch
@kriegaex
Well, then it is a matter of trust or at some point you shall be on your own. Just speaking for myself, I have absolutely no problem signing an NDA.
Good luck then.
Björn Lindahl
@blindahl
Appreciate your proposition though.
Alexander Kriegisch
@kriegaex
Feel free to report back whenever you can come up with anything resembling or even reproducing your problem. Leonard's knowledge is far superior to mine, he might be able to help you with way less information than I.
Björn Lindahl
@blindahl
We'll stick to going with SAME_THREAD and see if the error pop up somewhere else in the application leading us towords the issue. We're intrigued with why it occures as well so we won't ignore it completely.
Yeah, will for sure report back if it has to do with Spock.
Alexander Kriegisch
@kriegaex
FWIW, I love tricky problems. The easy ones can be boring to debug. ;-)
Björn Lindahl
@blindahl
Hehe :)
Björn Lindahl
@blindahl
A couple of other things with mentioning:
It's always same the tests that fail when they fail. They all fail when any of them fail. It's enough to annotate one spec file with SAME_THREAD to not make the tests fail. It doesn't have to be any spec containing the tests that fail occasionally but that's maybe a result of how SAME_THRED is implemented? I haven't fully grasped all detaild yet.
Alexander Kriegisch
@kriegaex
You might learn something about your problem if you abstract it, i.e. condense it down into a new project with similar characteristics. This is called an MCVE. While creating one, you might already find out what your problem is. If you don't but can reproduce the problem with the MCVe on your local machine or CI system, then the nice side effect is that you can share the MCVE with us and have a few more pairs of eyes inspecting it.
Is there any chance that you might have multiple Spock configurations on your CI system, maybe overriding each other in a strange way, making SAME_THREAD even necessary of effective beside runner.parallel.enabled=false? And are you sure, your Spock config is being picked up? You can just add diagnostic println statements to it, it is a Groovy file. Sorry for the unstructured brainstorming style of response, but I guess at this point any educated guess might be more helpful than none at all.
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 }

}