Trying to broaden the appeal of Spock at work and run into this issue. Actually trying to write Unit Tests for a Groovy class, but one that calls out to Java. A static method calls a private constructor. The code looks like:
private MyConfigurator(String zkConnectionString){
solrZkClient = new SolrZkClient(zkConnectionString, 30000, 30000,
new OnReconnect() {
@Override
public void command() { . . . }
});
}
"SolrZkClient" is from third party (Apache) Java library. Since it tries to connect to ZooKeeper, I would like to mock that out for this Unit Test (rather than running one internally as part of the unit test).
My test gets to the constructor without difficulty, but I can't get past that ctor:
def 'my test'() {
when:
MyConfigurator.staticMethodName('hostName:2181')
then:
// assertions
}
Is there anyway to do this?
Starting with Mockito version 3.5. 0, we can now mock Java constructors with Mockito. This allows us to return a mock from every object construction for testing purposes.
Faking static methods called in a constructor is possible like any other call. if your constructor is calling a method of its own class, you can fake the call using this API: // Create a mock for class MyClass (Foo is the method called in the constructor) Mock mock = MockManager. Mock<MyClass>(Constructor.
Spock is a testing and specification framework for Java and Groovy applications. What makes it stand out from the crowd is its beautiful and highly expressive specification language. Thanks to its JUnit runner, Spock is compatible with most IDEs, build tools, and continuous integration servers.
Since the class under test is written in Groovy, you should be able to mock the constructor call by way of a global Groovy Mock/Stub/Spy (see Mocking Constructors in the Spock Reference Documentation). However, a better solution is to decouple the implementation of the MyConfigurator
class, in order to make it more testable. For example, you could add a second constructor and/or static method that allows to pass an instance of SolrZkClient
(or a base interface, if there is one). Then you can easily pass in a mock.
You can use GroovySpy for mocking constructors in Spock
For example:
def 'my test'() {
given:
def solrZkClient = GroovySpy(SolrZkClient.class,global: true);
when:
MyConfigurator.staticMethodName('hostName:2181')
then:
// assertions
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With