Inject autowired object as mock into spock test in spring boot application

10.6k views Asked by At

I have a Spring Boot application and Service with private DAO field inside it. Private DAO property is annotated with @Autowired (no setters or constructors set it, just annotation). I tried to write Spock test for service, but can't find how to inject mock DAO into @Autowired variable.

class TestService extends Specification {
    DAO dao = Mock(DAO)
    Service service = new Service()

    def "test save"() {
        when:
        service.save('data')

        then:
        1 * dao.save('data')
    }
}

Any ideas?

UPD: I'm testing java code.

2

There are 2 answers

2
Vitaliy Borisok On BEST ANSWER

As result I did this:

class TestService extends Specification {
    DAO dao = Mock(DAO)
    Service service = new Service()

    void setup() {
        service.dao = dao
    }

    def "test save"() {
        when:
        service.save('data')

        then:
        1 * dao.save('data')
   }
}

One point was to use reflection. But Groovy can set private fields directly without additional manipulations. It was news for me.

0
ringadingding On

sorry to bring a little over a year old thread to life but here is my two cents. Groovy does provide access to private fields even though it break encapsulation. Just incase if you haven't figured it out, when you manually instantiate a class with Autowired fields, Autowired fields will be null. You can either provide setters for it and set them or groovy can see private fields anyways. However, if you have luxury I would suggest to refactor it to use constructor injection and do the same for any of your code in future. Field Injection and setter injections have some problems when it comes to testing.