Closed jamesflagg closed 10 years ago
Full unit test to reproduce:
import mockit.Cascading;
import mockit.Mocked;
import mockit.NonStrictExpectations;
import mockit.internal.state.ExecutingTest;
import org.junit.Test;
/**
* This test reproduces a suspected JMockit bug in JMockit 1.11.
*
* Use case:
* <ol>
* <li>We have a class which is Mocked for the unit test.
* <li>This class has a method which is recorded in an Expectations block.
* <li>The recorded method returns an Object type (not void or primitive or
* String).
* <li>We have a second class which happens to be in the same package as the
* first class, and whose name happens to start with the name of the first
* class.
* <li>The second class is annotated as a Cascading mock for the test.
* </ol>
*
* <p>
* Result: When recording the expectations block, a
* {@link NoSuchMethodException} is thrown and causes a test failure.
*
* <p>
* The issue seems to originate in {@link ExecutingTest}, method
* getCascade(String), line 354, where {@link String#startsWith(String)} is used
* and which seems to pick up the wrong class, causing the problem.
*
* @author James Flagg
*/
public class TestCascadingNameConflict {
class Apple {
// To reproduce this problem, the method to be mocked must return an
// Object type, not void or a primitive type.
public Slices slice() {
// Real implementation doesn't matter; will be mocked below.
return null;
}
}
// A second class whose name just happens to begin with the name of the
// first class.
class Applesauce {
}
// Not important, but the mocked/recorded method must return an Object type
class Slices {
}
@Mocked
Apple apple;
// This class, whose name begins with the name of the other Mocked class,
// must be marked as Cascading to reproduce the problem. If it's just
// "Mocked", then the test passes.
@Cascading
Applesauce applesauce;
@Test
public void myTest() {
// The following expectations block causes:
// java.lang.RuntimeException: java.lang.NoSuchMethodException:
// TestCascadingNameConflict$Applesauce.slice()
// Use of Expectations instead of NonStrictExpectations causes the same
// problem.
new NonStrictExpectations() {
{
apple.slice();
}
};
}
}
Thanks for the report; it's a weird bug, indeed.
Yes, perhaps a more realistic example is legacy code following a "value object" pattern, where two class names differ only by a suffix, e.g. "Employee" and "EmployeeVO". That's how I encountered it initially.
Use case:
Result : When recording the expectations block, a NoSuchMethodException is thrown and causes a test failure.