Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mocking the log object

I have such code:

@TestFor(MyService)
class MyServiceTests {
    void testIt() {
        def logTo = []
        def loggerMock = mockFor(service.log.class)
        loggerMock.demand.error(1..1) { String msg, Exception ex ->
            logTo << [level: 'error', msg: msg, ex: ex]
        }
        service.log = loggerMock.createMock()
    }
}

It fails with:

| Failure:  testIt(MyServiceTests)
|  java.lang.ArrayIndexOutOfBoundsException: 0
    at SLF4JLog_groovyProxy.<init>(Script1.groovy:4)
    at Script1.run(Script1.groovy:8)
    at grails.test.GrailsMock.createMock(GrailsMock.groovy:91)
    at package.MyServiceTests.testIt>>>(MyServiceTests.groovy:25)

pointing to the line service.log = loggerMock.createMock(). What's wrong with it?

like image 715
eugene82 Avatar asked Apr 02 '26 15:04

eugene82


1 Answers

This is a terribly uninformative error message that I've gotten when trying to Mock objects that don't have a 0-argument constructor. I don't know what class it is that you're trying to mock there, since you're getting it from another class' member, but I would check that it can be constructed as a Bean (with no arguments) and, if not, that's probably the issue.

Looking a little further, I'm guessing that the class SLF4JLog doesn't have a 0-argument constructor. In order to Mock it using mockFor, you'll need to do something along the lines of the following (note you'll need to determine what arguments are acceptable for a SLF4JLog constructor:

  void test_create_proxy_instance_with_constructor_arguments() {
    def mock = new MockFor(MockForTestClassWithConstructorArgs)
    mock.demand.amethod { "from mock with proxy"}

    def proxy = mock.proxyInstance(["value1", "value2"]as Object[])
    assertEquals "from mock with proxy", proxy.amethod()
    mock.verify proxy
  }

Source: http://groovy.codehaus.org/Using+MockFor+and+StubFor

This may be more involved than you need to get. I presume you're testing some class that uses a logger? Hopefully that class doesn't refer to that logger by class (static type), and uses 'def' instead. In that case, you can just pass in any old Stub (see the reference again) that happens to have all the 'methods' that your class calls on the Logger object.

like image 189
billjamesdev Avatar answered Apr 04 '26 07:04

billjamesdev



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!