Skip to content

Commit

Permalink
Add check to prevent double global mocking (#1792)
Browse files Browse the repository at this point in the history
Previous to this commit, it was possible to create a global
GroovyMock/Stub/Spy for a type that was already a global mock,
this is problematic and leaked the modified meta-class.
  • Loading branch information
leonard84 authored Sep 15, 2023
1 parent 36c984d commit 75ac394
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,13 @@ public boolean canCreate(IMockConfiguration configuration) {

@Override
public Object create(IMockConfiguration configuration, Specification specification) throws CannotCreateMockException {
final Class<?> type = configuration.getType();
final MetaClass oldMetaClass = GroovyRuntimeUtil.getMetaClass(configuration.getType());
if (oldMetaClass instanceof GroovyMockMetaClass) {
throw new CannotCreateMockException(type,
". The given type is already mocked by Spock.");
}
GroovyMockMetaClass newMetaClass = new GroovyMockMetaClass(configuration, specification, oldMetaClass);
final Class<?> type = configuration.getType();

if (configuration.isGlobal()) {
if (type.isInterface()) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,45 @@
package org.spockframework.smoke.mock

import org.spockframework.mock.CannotCreateMockException
import spock.lang.Specification
import spock.lang.Unroll

class GroovyMocks extends Specification {
def "implement GroovyObject"() {
expect:
GroovyMock(List) instanceof GroovyObject
GroovyMock(ArrayList) instanceof GroovyObject
}

@Unroll("A Groovy#typeB can't be created for a type that was already Groovy#typeA'd")
def "global GroovyMocks can't be created for a type that is already mocked"(String typeA, String typeB) {
given:
createMock(typeA)

when:
createMock(typeB)

then:
CannotCreateMockException e = thrown()
e.message == 'Cannot create mock for class java.util.ArrayList. The given type is already mocked by Spock.'

where:
[typeA, typeB] << ([['Mock', 'Stub', 'Spy']] * 2).combinations()
}

void createMock(String type) {
switch (type) {
case 'Mock':
GroovyMock(global: true, ArrayList)
break
case 'Stub':
GroovyStub(global: true, ArrayList)
break
case 'Spy':
GroovySpy(global: true, ArrayList)
break
default:
throw new IllegalArgumentException(type)
}
}
}

0 comments on commit 75ac394

Please sign in to comment.