Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 287
Vitaliy Borisok Avatar asked Dec 25 '22 18:12

Vitaliy Borisok


2 Answers

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.

like image 82
Vitaliy Borisok Avatar answered Mar 26 '23 19:03

Vitaliy Borisok


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.

like image 38
ringadingding Avatar answered Mar 26 '23 19:03

ringadingding