Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can Spock Mock a Java constructor

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?

like image 590
JoeG Avatar asked Jan 17 '14 19:01

JoeG


People also ask

Can we mock a constructor in Java?

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.

How do you mock a constructor method?

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.

What is Spock in Java?

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.


2 Answers

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.

like image 155
Peter Niederwieser Avatar answered Oct 07 '22 23:10

Peter Niederwieser


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
}
like image 1
Raghu K Nair Avatar answered Oct 07 '22 21:10

Raghu K Nair