keeganwitt / gmock

Automatically exported from code.google.com/p/gmock
6 stars 2 forks source link

Partial Mock does not work if the target's metaClass has been altered #94

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
1. Create Grails Service "MyService"
2. Add two methods to MyService: method one() should call method two()
3. Add @WithGMock to generated test class.
4. In setup() do the following to wire in a logger:

def myService

protected void setUp() {
   super.setUp()

   BasicConfigurator.configure()
   LogManager.rootLogger.level = Level.DEBUG
   log = LogManager.getLogger(MyService.class.name)

   MyService.class.metaClass.getLog << {-> log}

   myService = new MyService()
}

5. In test method for MyService.one() try to create a partial mock like so:

void testOne() {
   mock(myService).two()
   play {
      myService.one()
   }
}

6. Verify that the two() method is not mocked and the original two() method
on MyService is called.  Instead, the mocked two() method should be called.

What version of the product are you using? On what operating system?

0.8.0 on Windows XP running inside of IntelliJ IDEA Maia EAP

Please provide any additional information below.

Original issue reported on code.google.com by matthew....@gmail.com on 5 Nov 2009 at 6:52

GoogleCodeExporter commented 9 years ago
FYI I can get around this by using the metaClass on MyService to mock the two()
method in my one test and then null out the metaClass in my tearDown() method. 
Obviously, that's less than ideal.

Original comment by matthew....@gmail.com on 5 Nov 2009 at 7:41

GoogleCodeExporter commented 9 years ago
I tried the following script and it passed:

import org.gmock.GMockTestCase

@Grab(group = 'org.gmock', module = 'gmock', version = '0.8.0')
class Test extends GMockTestCase {
    def myService
    void setUp() {
        def log = 'log'
        MyService.class.metaClass.getLog << { -> log }
        myService = new MyService()
    }
    void testPartialMockingWithAlteredMetaClass() {
        mock(myService).two()
        play {
            myService.one()
        }
    }
}

class MyService {
    def one() {
        assert log == 'log'
        two()
    }
    def two() {
        throw new RuntimeException('The original method should not be called')
    }
}

Original comment by JohnnyJianHY on 6 Nov 2009 at 1:14

GoogleCodeExporter commented 9 years ago
I cannot reproduce this issue even in the environment of Grails 1.2.1

Original comment by JohnnyJianHY on 25 Feb 2010 at 9:21