0

My objective is to Mock the private variable in method of a service class in Grails.

Here I tried bellow way in my test method:

given: 'Mocking of object'
        def dataSource = Mock(TransactionAwareDataSourceProxy)
        def db1 = Mock(Sql)
        service.dataSource = dataSource

        new Sql(dataSource) >> db1

    List<GroovyRowResult> resultList = new ArrayList<>()
    GroovyRowResult result = new GroovyRowResult(id: 0)
    result.someAmount = 400
    resultList.add(result)

    db1.rows(_) >> resultList

In my service class my code is :

def db = new Sql(dataSource)
List<GroovyRowResult> resultList = db.rows("Select * from user_info")

Here, I successfully mocked the TransactionAwareDataSourceProxy named dataSource but I am failed to assign mock def db = new Sql(dataSource) into local private variable db.

I need bellow solution:

  1. How to mock the private variable inside a method. Here, I am assigning Sql in private variable db in my service method

Thanks in advance

Md. Sajedul Karim
  • 6,749
  • 3
  • 61
  • 87

1 Answers1

2

The simple answer is: You don't. Instead you refactor to be able to use dependency injection, i.e. pass the Sql instance into the method or into the class. Then you can easily mock it.

See also here and in the other answers linked off of that answer.


The "don't do this at home, kids" part which I do not recommend because it only works for Groovy classes under test and also helps establish bad design in your application code: You can use Spock's Groovy mocks in order to mock constructors. You could achieve the same for Java classes using Mockito, Powermock or my own tool Sarek. Sarek even works for JRE bootstrap classes, also final ones.

But whenever you need Groovy mocks or special add-on tools while writing Spock tests, it is usually a sign you should refactor instead. Only in rare cases where you need to mock something in third party code you are unable to modify, you might need such tools. But even then you can usually refactor your own code in order to access the third party code in such a way that you can inject the right kind of test double (mock, stub, spy) preconfigured to behave like you need it to.

kriegaex
  • 63,017
  • 15
  • 111
  • 202