orbfish
orbfish

Reputation: 7731

Cannot Mockito spy class in Spock test?

I'm trying to spy a Java class in a Spock test. I've not had a problem with Mockito in Spock/Groovy before.

When I try to do the following:

def service = spy(Service.class)

I get the following error:

org.mockito.exceptions.base.MockitoException: 
Cannot mock/spy class java.lang.Class
Mockito cannot mock/spy following:
  - final classes
  - anonymous classes
  - primitive types

When I do mock(Service.class) though, it works fine.

I have confirmed that the class is not final, anonymous, or primitive.

Any ideas? I have a random generator in the class (ak) so I need to spy not mock.

Thank you

Upvotes: 1

Views: 8931

Answers (2)

Thalescm
Thalescm

Reputation: 155

Just an extra to Ray's answer, you can also spy on already created instances. The only thing is that all methods you called before spy() was called, cannot be verified. Like:

ClassToSpy spiedInstance;

@Before
public void before () {
    spiedInstance = new ClassToSpy();
}

@Test
public void testWillFail() {
    spiedInstance.method();
    spiedInstance = spy(spiedInstance);

    verify(spiedInstance).method();
}

@Test
public void testWillPass() {
    spiedInstance = spy(spiedInstance);
    spiedInstance.method();

    verify(spiedInstance).method();
}

The error you would get from testWillFail would be similar to:

Wanted but not invoked:
classToSpy.method();
-> at your.package.testWillFail(TestClass.java:line)
Actually, there were zero interactions with this mock.

Due to the fact that, after spied, you did not call this method.

Upvotes: 0

Ray
Ray

Reputation: 3201

Mockito doesn't spy on Classes (or Mocks), it spies on (regular) Objects. Thus, instead of

def service = spy(Service.class)

you have to write

def service = spy(new Service())

(or whichever constructor is appropriate for your scenario).

Upvotes: 3

Related Questions