jmockit / jmockit1 Goto Github PK
View Code? Open in Web Editor NEWAdvanced Java library for integration testing, mocking, faking, and code coverage
License: Other
Advanced Java library for integration testing, mocking, faking, and code coverage
License: Other
After upgrading from 1.0 to 1.9, I started getting these IndexOutOfBoundsExceptions. Here is the relevant part of the exception:
java.lang.IndexOutOfBoundsException: Index: 10, Size: 7
at java.util.ArrayList.rangeCheck(ArrayList.java:638)
at java.util.ArrayList.get(ArrayList.java:414)
at mockit.internal.state.MockInstances.getMock(MockInstances.java:27)
at mockit.internal.state.MockClasses.getMock(MockClasses.java:39)
at mockit.internal.state.TestRun.getMock(TestRun.java:119)
This is happening on a large project with lots of submodules. When testing all of them this exception is thrown, but if running them individually there is no problem.
Unfortunately I've been unable to isolate and reproduce this on a separate test, so it's hard to have an idea about what might be causing this.
I tried to downgrade to 1.8 and the number of exceptions went from 11 in 850 tests to about 200.
Hi,
I know the @mocked is great, but is there any way we can create mock manually and use them in Expectations API? I mean I want to have a function to generate mock objects on demand while still able to create non-mocked objects. We have the @Injectable, why can't we create mock objects on demand?
Hi again,
Could you help me with the following error ?
java.lang.IllegalStateException: Attempted to record invocation to mocked method from outside expectation block.
JMockit Version 1.10.
JDK 1.7.0_51
OS Win7 64bit
I have an Expectation block that mocks several methods, and then it invokes a high level function to verify that those functions are being called. However I am getting the above error.
I suspect that the reason for this error is because one of the functions that I do mock, internally calls another mocked function( mocked in the same expectation block).
As the code I am testing is proprietary I am not allowed to post it here.
Any directions on how to fix this error greatly appreciated. Thanks.
After updating to the latest version of jmockit I noticed that my Pitest run started failing.
I did a bit of research and figured out that the problem has been introduced between r2822 (successful) and r2825 (failing). See https://code.google.com/p/jmockit/source/list
The intermediary revisions fail to compile so I couldn't get a more precise position of the introduction of the regression.
The result is a successful run against r2822 while r2825 gives the following stacktrace
java.lang.StackOverflowError
at mockit.integration.testng.internal.TestNGRunnerDecorator$MockParameters.getInjectedParameter(TestNGRunnerDecorator.java:46)
at org.testng.internal.Parameters.getInjectedParameter(Parameters.java)
at mockit.integration.testng.internal.TestNGRunnerDecorator$MockParameters.getInjectedParameter(TestNGRunnerDecorator.java:46)
at org.testng.internal.Parameters.getInjectedParameter(Parameters.java)
at mockit.integration.testng.internal.TestNGRunnerDecorator$MockParameters.getInjectedParameter(TestNGRunnerDecorator.java:46)
Now this is the (horrible) protocol I used to run my test:
#!/bin/sh
set -ex
#I didn't bother with a temporary repository
# I just removed the "org/jmockit/jmockit/1.10/" when I was done
jmockit_dir=~/Documents/jmockit1
raven_dir=~/Documents/raven-java
#Jmockit 1.9 needs Java7
JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.7.0_65.jdk/Contents/Home
cd "$jmockit_dir/main"
mvn clean package -DskipTest -Dmaven.test.skip=true -Dmaven.javadoc.skip=true
mv -f target/jmockit-1.9.jar ~/.m2/repository/org/jmockit/jmockit/1.10/jmockit-1.10.jar
cd "$raven_dir/raven"
mvn org.pitest:pitest-maven:mutationCoverage -P pitest
against the current master of my project (getsentry/sentry-java@4df7dba)
I would love to be able to provide more details, unfortunately Pitest is a bit of a black box for me ATM
Is this the intended behavior? Or we can do it differently?
JMockit 1.10
TestNG 6.8.6.20141201_2240 (eclipse plug-in)
JDK 1.8
Some part of the the bug reported previously on Google's issue tracker, Issue 350, which was totally fixed by version 1.9, is back again in version 1.10. Specifically, the test case genericsFailure_ClassCast2, provided by the test suite attached to that reported issue, now fails again with the following error:
FAILED: genericsFailure_ClassCast2(tests.JMockitGenericsFailureTests$BackImpl@5ae63ade)
java.lang.IllegalArgumentException: tests.JMockitGenericsFailureTests$AppImpl is not an interface
at java.lang.reflect.Proxy$ProxyClassFactory.apply(Proxy.java:590)
at java.lang.reflect.Proxy$ProxyClassFactory.apply(Proxy.java:557)
at java.lang.reflect.WeakCache$Factory.get(WeakCache.java:230)
at java.lang.reflect.WeakCache.get(WeakCache.java:127)
at java.lang.reflect.Proxy.getProxyClass0(Proxy.java:419)
at java.lang.reflect.Proxy.newProxyInstance(Proxy.java:719)
at tests.JMockitGenericsFailureTests$BackImpl.getApp(JMockitGenericsFailureTests.java)
at tests.JMockitGenericsFailureTests$3.<init>(JMockitGenericsFailureTests.java:127)
at tests.JMockitGenericsFailureTests.genericsFailure_ClassCast2(JMockitGenericsFailureTests.java:124)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.lang.reflect.Method.invoke(Method.java:483)
If a @tested class has a method annotated with javax.annotations.PostConstruct, it should be executed right after injection.
Hi there,
So my issues is that I am getting the following error
java.lang.VerifyError
at sun.instrument.InstrumentationImpl.redefineClasses0(Native Method)
at someClass$MocksomeClass.(MyTestFile.java:10)
Please note that, I have replaced the actual mocked class with someClass .
I am trying to mock the constructor of a object that lives in a third party library.
The code in the library is compiled used Java 1.6 .
The Java I am using is 1.7.0_51.
JMocking Version 1.10.
OS Win7 64 bit.
The way I'm trying to mock the constructor is like this :
public static class MocksomeClass extends MockUp {
private someObject ;
@mock public void $init(someClass object) {
this.someObject = object;
}
}
When I try to instantiate this class I get the above stack trace. Any help greatly appreciated.
Hi,
I get the following stack trace trying to run tests with JMockit:
Ausnahmebedingung in Thread "main"# START NON-TRANSLATABLEjava.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:60)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)
at java.lang.reflect.Method.invoke(Method.java:611)
at sun.instrument.InstrumentationImpl.loadClassAndStartAgent(InstrumentationImpl.java:335)
at sun.instrument.InstrumentationImpl.loadClassAndCallPremain(InstrumentationImpl.java:350)
Caused by: java.lang.ClassFormatError: JVMCFRE009 Schnittstellenfeld muss 'public', 'static' oder 'final' sein.; Klasse=org/omg/CORBA/portable/IDLEntity, Offset=198
at com.ibm.oti.vm.VM.findClassOrNull(Native Method)
at com.ibm.oti.vm.BootstrapClassLoader.loadClass(BootstrapClassLoader.java:62)
at com.ibm.oti.vm.VM.findClassOrNull(Native Method)
at com.ibm.oti.vm.BootstrapClassLoader.loadClass(BootstrapClassLoader.java:62)
at java.lang.ClassLoader.loadClassHelper(ClassLoader.java:655)
at java.lang.ClassLoader.loadClass(ClassLoader.java:644)
at java.lang.ClassLoader.loadClassHelper(ClassLoader.java:657)
at java.lang.ClassLoader.loadClass(ClassLoader.java:644)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:358)
at java.lang.ClassLoader.loadClass(ClassLoader.java:627)
at mockit.internal.startup.MockingBridgeFields.createSyntheticFieldsInJREClassToHoldMockingBridges(MockingBridgeFields.java:30)
at mockit.internal.startup.Startup.initialize(Startup.java:57)
at mockit.internal.startup.Startup.premain(Startup.java:49)
... 6 more
Used to work well with prior versions of JMockit, including 1.9, only changed JMockit version to 1.10.
Any ideas why it won't work anymore?
JMockit: 1.10
JRE: WebSphere Application Servers V8.5 JRE (Java 1.7)
JUnit: 4.10
I observed the following runtime failure when using JMockit 1.9 with Robolectric 2.2. The JMockit library is declared at the beginning of the Maven dependency list.
Please advise. Thanks!
java.lang.IllegalArgumentException: attempted to invoke public void org.robolectric.shadows.ShadowConfiguration.constructor(android.content.res.Configuration) on instance of class org.robolectric.shadows.ShadowConfiguration, but ShadowConfiguration doesn't extend ShadowConfiguration
at android.content.res.Configuration.(Configuration.java:425)
at org.robolectric.shadows.ShadowResources.setSystemResources(ShadowResources.java:82)
at org.robolectric.internal.ParallelUniverse.setUpApplicationState(ParallelUniverse.java:57)
at org.robolectric.RobolectricTestRunner.setUpApplicationState(RobolectricTestRunner.java:404)
at org.robolectric.RobolectricTestRunner$2.evaluate(RobolectricTestRunner.java:220)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.robolectric.RobolectricTestRunner$1.evaluate(RobolectricTestRunner.java:175)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:264)
at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:153)
at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:124)
at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:200)
at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:153)
at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:103)
The current sources (https://github.com/jmockit/jmockit1/blob/master/main/src/mockit/internal/util/DefaultValues.java) do require Java 8 for compile (while the source/target level in build.xml
is 1.6
). Is my understanding correct? Thanks
(Are there some developer setup pointers documented which I have missed?)
From issue 344 in the old issue tracker at Google Code:
Given a tested class with a single public constructor having several parameters of distinct types, and an @Injectable field in the test class for each parameter, the following exception was reported to occur:
java.lang.IllegalArgumentException: No constructor in class com.murex.processing.plugins.ppsconnector.utility.UtilityServiceImpl that can be satisfied by available injectables
I think it’s worth it for the code to take the time and include in the exception message at least:
In other words, rather than:
java.lang.IllegalArgumentException: No constructor in class my.TestedClass that can be satisfied by available injectables
It should say something like this:
java.lang.IllegalArgumentException: No constructor in class my.TestedClass that can be satisfied by available injectables:
Candidate constructor my.TestedClass.TestedClass(A, B, C) cannot be satisfied:
Argument 1 cannot be satisfied:
) there are no fields of parameters of type A (or “assignable to A”, I’m not sure of the rules here)
Argument 2 cannot be satisfied:
*) candidate field my.TestedClassUnitTests.instanceA is not annotated with @Injectable
Argument 3 is satisfied by field my.TestedClassUnitTests.instanceC:
*) argument 2 of my.TestedClassUnitTests.testSomething(C, C) matches but / reason this was not preferred /
*) field my.TestedClassUnitTests.instanceC2 / idem */
Candidate constructor my.TestedClass.TestedClass(A, D) cannot be satisfied:
Argument 1 cannot be satisfied (see above)
Argument 2 cannot be satisfied /* whatever reason */
Mainly for Optional, Stream, and Spliterator.
In JMockit 1.8, Robolectric-based tests using JMockit to mock Android classes were working, but changes in version 1.9 broke them.
In Netbeans 8.0, it appears that TestNG is always in the classpath (though maybe only in a Glassfish-based web app, not verified yet in other types of projects). When running a JUnit test class, the JMockit-JUnit integration is not correctly initialized, and mocking is not applied to mock parameters, etc.
JMockit 1.9 introduced a behavior change where a lot of tests that were passing previously now fail with the error message: "Class is already mocked: ..."
This can be easily reproduced by the attached test.
It seems that, at least in certain cases, the JVM shutdown hook thread used by the coverage tool gets killed before it completes normally. Maven documentation asks users to avoid such hooks.
A better solution to generate coverage output at the end of a test run should be to use a JUnit/TestNG hook for that.
I'm seeing these errors (related to non-Unicode chars in the source?):
[javac] Compiling 151 source files to c:\tmp\jmockit1\main\test-classes
[javac] c:\tmp\jmockit1\main\test\mockit\ExpectationsUsingReturnTypeConversionTest.java:115: error: unclosed character literal
[javac] mock.getDouble(); result = 54321; result = 'á';
[javac] ^
[javac] c:\tmp\jmockit1\main\test\mockit\ExpectationsUsingReturnTypeConversionTest.java:115: error: illegal character: '\u00a1'
[javac] mock.getDouble(); result = 54321; result = 'á';
[javac] ^
[javac] c:\tmp\jmockit1\main\test\mockit\ExpectationsUsingReturnTypeConversionTest.java:115: error: unclosed character literal
[javac] mock.getDouble(); result = 54321; result = 'á';
[javac] ^
[javac] c:\tmp\jmockit1\main\test\mockit\ExpectationsUsingReturnTypeConversionTest.java:132: error: unclosed character literal
[javac] assertEquals('á', mock.getDouble(), 0);
[javac] ^
[javac] c:\tmp\jmockit1\main\test\mockit\ExpectationsUsingReturnTypeConversionTest.java:132: error: illegal character: '\u00a1'
[javac] assertEquals('á', mock.getDouble(), 0);
[javac] ^
[javac] c:\tmp\jmockit1\main\test\mockit\ExpectationsUsingReturnTypeConversionTest.java:132: error: unclosed character literal
[javac] assertEquals('á', mock.getDouble(), 0);
[javac] ^
[javac] c:\tmp\jmockit1\main\test\mockit\ExpectationsUsingReturnTypeConversionTest.java:132: error: ';' expected
[javac] assertEquals('á', mock.getDouble(), 0);
[javac] ^
[javac] c:\tmp\jmockit1\main\test\mockit\ExpectationsUsingReturnTypeConversionTest.java:132: error: ';' expected
[javac] assertEquals('á', mock.getDouble(), 0);
[javac] ^
[javac] c:\tmp\jmockit1\main\test\mockit\ExpectationsUsingReturnTypeConversionTest.java:173: error: unclosed character literal
[javac] mock.getByteWrapper(); result = 'ç';
[javac] ^
[javac] c:\tmp\jmockit1\main\test\mockit\ExpectationsUsingReturnTypeConversionTest.java:173: error: illegal character: '\u00a7'
[javac] mock.getByteWrapper(); result = 'ç';
[javac] ^
[javac] c:\tmp\jmockit1\main\test\mockit\ExpectationsUsingReturnTypeConversionTest.java:173: error: unclosed character literal
[javac] mock.getByteWrapper(); result = 'ç';
[javac] ^
[javac] c:\tmp\jmockit1\main\test\mockit\ExpectationsUsingReturnTypeConversionTest.java:185: error: unclosed character literal
[javac] assertEquals((byte) 'ç', mock.getByteWrapper().byteValue());
[javac] ^
[javac] c:\tmp\jmockit1\main\test\mockit\ExpectationsUsingReturnTypeConversionTest.java:185: error: illegal character: '\u00a7'
[javac] assertEquals((byte) 'ç', mock.getByteWrapper().byteValue());
[javac] ^
[javac] c:\tmp\jmockit1\main\test\mockit\ExpectationsUsingReturnTypeConversionTest.java:185: error: unclosed character literal
[javac] assertEquals((byte) 'ç', mock.getByteWrapper().byteValue());
[javac] ^
[javac] c:\tmp\jmockit1\main\test\mockit\ExpectationsUsingReturnTypeConversionTest.java:185: error: ';' expected
[javac] assertEquals((byte) 'ç', mock.getByteWrapper().byteValue());
[javac] ^
[javac] c:\tmp\jmockit1\main\test\mockit\ExpectationsUsingReturnTypeConversionTest.java:185: error: ';' expected
[javac] assertEquals((byte) 'ç', mock.getByteWrapper().byteValue());
[javac] ^
[javac] 16 errors
Could you please comment? Thanks
There is no history at all. Why was the history of changes dropped or not migrated from SVN repo?
When using @mocked, @Cascading etc on org.apache.maven.project.MavenProject, the following exception occurs
java.lang.InternalError
at sun.instrument.InstrumentationImpl.retransformClasses0(Native Method)
at sun.instrument.InstrumentationImpl.retransformClasses(InstrumentationImpl.java:144)
at mockit.internal.startup.Startup.retransformClass(Startup.java:231)
at mockit.internal.state.CachedClassfiles.getClassfile(CachedClassfiles.java:95)
at mockit.internal.ClassFile.createReaderOrGetFromCache(ClassFile.java:60)
at mockit.internal.expectations.mocking.BaseTypeRedefinition.redefineClassAndItsSuperClasses(BaseTypeRedefinition.java:186)
at mockit.internal.expectations.mocking.BaseTypeRedefinition.redefineMethodsAndConstructorsInTargetType(BaseTypeRedefinition.java:180)
at mockit.internal.expectations.mocking.BaseTypeRedefinition.redefineTargetClassAndCreateInstanceFactory(BaseTypeRedefinition.java:264)
at mockit.internal.expectations.mocking.BaseTypeRedefinition.redefineType(BaseTypeRedefinition.java:65)
at mockit.internal.expectations.mocking.TypeRedefinition.redefineType(TypeRedefinition.java:39)
at mockit.internal.expectations.mocking.SharedFieldTypeRedefinitions.redefineTypeForMockField(SharedFieldTypeRedefinitions.java:60)
at mockit.internal.expectations.mocking.FieldTypeRedefinitions.redefineFieldType(FieldTypeRedefinitions.java:50)
at mockit.internal.expectations.mocking.FieldTypeRedefinitions.redefineFieldTypes(FieldTypeRedefinitions.java:38)
at mockit.internal.expectations.mocking.SharedFieldTypeRedefinitions.redefineTypesForTestClass(SharedFieldTypeRedefinitions.java:43)
at mockit.integration.internal.TestRunnerDecorator.handleMockFieldsForWholeTestClass(TestRunnerDecorator.java:134)
at mockit.integration.internal.TestRunnerDecorator.updateTestClassState(TestRunnerDecorator.java:42)
at mockit.integration.junit4.internal.JUnit4TestRunnerDecorator.handleMockingOutsideTestMethods(JUnit4TestRunnerDecorator.java:115)
at mockit.integration.junit4.internal.JUnit4TestRunnerDecorator.invokeExplosively(JUnit4TestRunnerDecorator.java:36)
at mockit.integration.junit4.internal.MockFrameworkMethod.invokeExplosively(MockFrameworkMethod.java:40)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:74)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:211)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:67)
Same problem with JDK 7 or JDK 8
Same project/classpath setup works fine for other types
Enum types with per-element methods currently can only be mocked with @capturing, because of the fact that the compiler puts those method implementations into subclasses of the enum.
This is not obvious to the user, and must be avoided; use of @mocked should be enough in this case as well.
Trying to use withCapture to validate the object passed to a method, but if the method is never called a null pointer exception is raised on the assert statement following the withCapture instead of a missing invocation error. The missing invocation is a preferred response since it clearly states that the method was never called.
Code snipet where ops is a mocked object. Ops is not used in any Expectations prior to verification. And the current implementation does not call ops.add(alarm).
new Verifications() {{
Alarm alarm;
ops.add(alarm = withCapture());
times = 1;
assertEquals(...
}}
Using version 1.10.
While reviewing the tutorial, I noticed that the test case on topic Specifying behavior for future instances fails with JMockit 1.9 and 1.10:
FAILED: testWithDifferentBehaviorForFirstNewInstanceAndRemainingNewInstances($Subclass_Buffer@6321e813, $Subclass_Buffer@6737fd8f)
java.lang.AssertionError: expected [10] but found [20]
at tests.JMockitTests.testWithDifferentBehaviorForFirstNewInstanceAndRemainingNewInstances(JMockitTests.java:229)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.lang.reflect.Method.invoke(Method.java:483)
It seems that the maxInstance=1
attribute on @Capturing
is not in effect.
For integration testing purposes, it would be very useful that @tested could still be used, with dependencies getting automatically injected with real instances (recursively) where no @Injectables were provided.
The main use case is the creation of integration tests for Java EE 6+ application classes. For example, tests for JSF backing beans which exercise the whole stack, including all EJBs and the database through a JPA EntityManager.
Hello,
I'm trying to use JMockit Path coverage and for the below code it is identifying 3 paths rather than two. Am i doing something wrong?
JMockit is saying this :Path coverage: 2/3 A: 1 B: 1 C: 0
public boolean getAgeDescriptionUsingDirect(int age) {
if (age == 0) {
return true;
}
if (age != 0) {
return false;
}
return true;
}
Thanks in advance
Issue:
I have a mock class that extends MockUp
. When running tests in JMockIt 1.9, the tests fail with java.lang.VerifyError
. This is through Maven on OSX.
$ mvn --version
Apache Maven 3.2.1 (ea8b2b07643dbb1b84b6d16e1f08391b666bc1e9; 2014-02-14T09:37:52-08:00)
Maven home: /usr/local/Cellar/maven/3.2.1/libexec
Java version: 1.7.0_45, vendor: Oracle Corporation
Java home: /Library/Java/JavaVirtualMachines/jdk1.7.0_45.jdk/Contents/Home/jre
Default locale: en_US, platform encoding: UTF-8
OS name: "mac os x", version: "10.9.4", arch: "x86_64", family: "mac"
I rolled back JMockIt to 1.8 and the tests passed again. Also, tests seem to work in IntelliJ on 1.9 with standard configuration run. Code is below.
Created a mock class that mocks org.mongojack.DBCursor
import mockit.Mock;
import mockit.MockUp;
import org.mongojack.DBCursor;
import org.mongojack.JacksonDBCollection;
import java.util.List;
public class DBCursorMock<T> extends MockUp<DBCursor<T>> {
private List<T> items = null;
public DBCursorMock (List<T> items) {
this.items = items;
}
@Mock
public void $init (JacksonDBCollection<T, ?> jacksonDBCollection,
com.mongodb.DBCursor cursor) {
}
@Mock
public List<T> toArray () {
return items;
}
}
Class is called in test like so:
JacksonDBCollectionMock<User, ObjectId> collection = new JacksonDBCollectionMock<>();
collection.setDBObjectItems(userList);
new DBCursorMock<>(userList);
(Note: JacksonDBCollectionMock is another mock that does not have an $init method.)
Stack trace:
testGetPasscode(net.foodjudge.apiserver.db.DeviceAtomicsTest) Time elapsed: 0.02 sec <<< ERROR!
java.lang.VerifyError
at sun.instrument.InstrumentationImpl.redefineClasses0(Native Method)
at net.foodjudge.mock.DBCursorMock.<init>(DBCursorMock.java:20)
at net.foodjudge.apiserver.db.DeviceAtomicsTest.testGetPasscode(DeviceAtomicsTest.java:127)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:252)
at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:141)
at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:112)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:189)
at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:165)
at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:85)
at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:115)
at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:75)
See code and details in issue 356 in the Google Code issue tracker.
Hi again,
I want to report an issue I discovered recently.
When one mocks the Thread.getName method, a StackOverFlow occurs. I did debug the code, and it turns out that JMockit internal classes use the Thread.getName method. So when I mock it, an infinite recursion occurs.
Thanks.
JMockit Version 1.10.
JDK 1.7.0_51
OS Win7 64bit
public class FooTest {
@Test
public void blahblah() {
MockUp<Thread> Mockthread = new MockUp<Thread>() {
@Mock
public String getName() {
return "Fake Thread";
}
};
Thread thread = Mockthread.getMockInstance();
System.out.println(thread.getName());
}
I cloned jmockit from Git. When building there seem to be a dependency to a number of jars in the lib/
directory (and also a small change was required to build.xml
):
annotations-13.0.jar
hamcrest-core-1.3.jar
javax.inject-1.jar
junit-4.11.jar
org.jacoco.ant-0.7.1.201405082137-nodeps.jar
persistence-api-1.0.2.jar
testng-6.8.jar
Are you interested in a pull request adding these? Thanks
From the JMockit Users mailing list:
https://groups.google.com/forum/#!topic/jmockit-users/RMJpJnBffvs
I have two interfaces and I am mocking one method on each one. I'm using the @capturing annotation. But simply having the @mocked parameters in a different order causes one of the interfaces to not be mocked.
(The same happens if the @mocked parameters are fields of the test class - the order matters)
The code below has two identical tests. One fails only because the parameters are in a different order. (I believe that both tests should pass)
code:
import mockit.Capturing;
import mockit.Mocked;
import mockit.NonStrictExpectations;
import mockit.integration.junit4.JMockit;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(JMockit.class)
public class InterfaceMocks {
public static interface I1 {
Double num();
String other();
}
public static interface I2 {
I1 getI1();
String method();
}
@Test
public void testGood(@Mocked("num") @Capturing final I1 i1Mock, @Mocked("getI1") @Capturing final I2 i2Mock) {
new NonStrictExpectations() {
{
i1Mock.num();
result = null;
i2Mock.getI1();
result = null;
}
};
I2 i2 = new I2() {
@Override
public I1 getI1() {
throw new RuntimeException();
}
@Override
public String method() {
throw new RuntimeException();
}
};
I1 i1 = i2.getI1();
}
@Test
public void testBad(@Mocked("getI1") @Capturing final I2 i2Mock, @Mocked("num") @Capturing final I1 i1Mock) {
new NonStrictExpectations() {
{
i1Mock.num();
result = null;
i2Mock.getI1();
result = null;
}
};
I2 i2 = new I2() {
@Override
public I1 getI1() {
throw new RuntimeException();
}
@Override
public String method() {
throw new RuntimeException();
}
};
I1 i1 = i2.getI1();
}
}
From issue 345 in the old issue tracker at Google Code:
public class ExampleTest
{
static class BBC {
final String x;
public BBC(String x) { this.x = x; }
}
static class ABC extends BBC {
public ABC(String x) { super(x); }
public static int getVal() { return 3; }
}
@Test
public void jmockitTest() {
new NonStrictExpectations(ABC.class) {{
ABC.getVal(); result = 4;
}};
assertEquals(4, ABC.getVal());
String x = "test";
ABC abc = new ABC(x);
assertEquals(x, abc.x);
}
}
BUG : Here the BBC class gets instantiated with the value of String null.
With the move to github, will you be moving old issues & comments over from google code? They're handy for reference, e.g. finding that an issue I'm having was already reported and fixed in a version of jMockit later than what I happen to be using.
import java.io.File;
import mockit.Mocked;
import mockit.NonStrictExpectations;
import org.testng.annotations.Test;
public class MockFileInvestigation {
@Test
public void test(@Mocked File f1) {
new NonStrictExpectations() {
};
}
}
When run this, the log shows the test passed, however with an NullPointerException.
pls check the log:
[TestNG] Running:
/tmp/testng-eclipse-1285965114/testng-customsuite.xml
PASSED: test("")
Default test
Tests run: 1, Failures: 0, Skips: 0
Default suite
[TestNG] Time taken by org.testng.reporters.EmailableReporter2@19f9e414: 13 ms
[TestNG] Time taken by org.testng.reporters.SuiteHTMLReporter@261b66ea: 88 ms
[TestNG] Time taken by [FailedReporter passed=0 failed=0 skipped=0]: 0 ms
[TestNG] Time taken by org.testng.reporters.JUnitReportReporter@5076ec1a: 5 ms
[TestNG] Reporter org.testng.reporters.XMLReporter@13707ac failed
java.lang.NullPointerException
at org.testng.reporters.XMLStringBuffer.addCDATA(XMLStringBuffer.java:297)
at org.testng.reporters.XMLSuiteResultWriter.addParameter(XMLSuiteResultWriter.java:266)
at org.testng.reporters.XMLSuiteResultWriter.addTestMethodParams(XMLSuiteResultWriter.java:250)
at org.testng.reporters.XMLSuiteResultWriter.addTestResult(XMLSuiteResultWriter.java:154)
at org.testng.reporters.XMLSuiteResultWriter.addTestResults(XMLSuiteResultWriter.java:130)
at org.testng.reporters.XMLSuiteResultWriter.writeAllToBuffer(XMLSuiteResultWriter.java:74)
at org.testng.reporters.XMLSuiteResultWriter.writeSuiteResult(XMLSuiteResultWriter.java:52)
at org.testng.reporters.XMLReporter.writeSuiteToBuffer(XMLReporter.java:120)
at org.testng.reporters.XMLReporter.writeSuite(XMLReporter.java:86)
at org.testng.reporters.XMLReporter.generateReport(XMLReporter.java:63)
at org.testng.TestNG.generateReports(TestNG.java:1094)
at org.testng.TestNG.run(TestNG.java:1053)
at org.testng.remote.RemoteTestNG.run(RemoteTestNG.java:111)
at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:204)
at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:175)
[TestNG] Time taken by org.testng.reporters.jq.Main@5f83bcb8: 74 ms
This issue leads to maven build fail.
If change the class to other class, it works ok.
I tried to create test for one method, it is similar to the sample code:
http://jmockit.googlecode.com/svn/trunk/www/tutorial/BehaviorBasedTesting.html#argumentMatching
Part:
Instances created with a given constructor
But what I need mock are several file instances.
Cannot find any anywhere, would you please kindly do me a favor and let me know this is an issue or my misunderstanding?
Thanks.
Partial mocking of an instance is not possible in more than one NonStrictExcpectations blocks. This prevents creating reusable methods that do mock a specific method of a given instance to make the test code more readable.
In the following example the method mockBothMethodsAtOnce succeeds and the method mockBothMethodsSuccessively fails with the exception:
java.lang.IllegalArgumentException: Class is already mocked: class PartialMockAnInstanceTest$ClassToPartialMock
Example:
public class PartialMockAnInstanceTest
{
@Test public void mockBothMethodsAtOnce() throws Exception {
final ClassToPartialMock classToPartialMock = new ClassToPartialMock();
new NonStrictExpectations( classToPartialMock ) {{
classToPartialMock.getA(); result = "mockedA";
classToPartialMock.getB(); result = "mockedB";
}};
}
@Test public void mockBothMethodsSuccessively() throws Exception {
final ClassToPartialMock classToPartialMock = new ClassToPartialMock();
new NonStrictExpectations( classToPartialMock ) {{
classToPartialMock.getA(); result = "mockedA";
}};
new NonStrictExpectations( classToPartialMock ) {{
classToPartialMock.getB(); result = "mockedB";
}};
}
private class ClassToPartialMock {
public String getA() { return "A"; }
public String getB() { return "B"; }
}
}
import mockit.Mock;
import mockit.MockUp;
import mockit.Mocked;
import org.junit.Test;
import javax.servlet.ServletOutputStream;
import static org.junit.Assert.assertNotNull;
/**
Created by ruyang on 7/23/2014.
*/
public class Playgroud {
class A {
private void doNothing() {}
public void doSomething(int i) {}
}
@test
public void mockServletOutputStream() {
ServletOutputStream stream = new MockUp() {
@mock
public void $clinit() { /* do nothing */ }
@mock
public void $init() {}
}.getMockInstance();
assertNotNull(stream);
}
@test
public void doSomething() {
A a = new MockUp() {
@mock void doNothing() {}
}.getMockInstance();
assertNotNull(a);
}
}
my assertions are failing, checked 1.9 source code, it seems caused by
private T redefineClassOrImplementInterface(@NotNull Class classToMock, @nullable Type typeToMock)
{
if (classToMock.isInterface()) {
return new MockedImplementationClass(this).generate(classToMock, typeToMock);
}
classesToRestore = redefineMethods(classToMock, typeToMock);
return null;
}
it should return mocked object, not null.
I have a project that I am putting unit tests together against and after upgrading to JMockit 1.10 are now receiving the following exception when running these unit tests from within both EclEmma and Cobertura:
java.lang.LinkageError: loader (instance of sun/misc/Launcher$AppClassLoader): attempted duplicate class definition for name: "my/package/TestMyClass$3"
I initially started with JUnit (4.11) tests but have since migrated these across to TestNG (6.8.8) with the same issue. When I run these unit tests alone, they all pass (JUnit and TestNG), however when I attempt to get code coverage from within Eclipse a number of these appear to fail with the linkage error above.
I have also downgraded to JMockit 1.9 and most of my tests pass except for a couple which require functionality in 1.10 so I am assuming that there is some sort of incompatibility between JMockit and the code coverage tools I have been using.
I am using:
I have been able to recreate this in a small example below.
I have an EJB that looks like the following
package my.pkg;
import javax.inject.Singleton;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
@Singleton
public class MyBean {
@PersistenceContext
private EntityManager em;
public Object doSomething (String value) {
Query query = em.createNamedQuery("SomeQuery");
Object objReturned = query.getSingleResult();
return objReturned;
}
}
I then have the TestNG class as follows:
package my.pkg;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import mockit.Expectations;
import mockit.Injectable;
import mockit.Mocked;
import mockit.Tested;
import org.testng.annotations.Test;
public class TestMyBean {
@Tested MyBean myBean;
@Mocked Query query;
@Test public void
should_test_something(@Injectable final EntityManager em) {
new Expectations() {{
em.createNamedQuery(anyString); returns (query);
query.getSingleResult(); returns (new Object());
}};
myBean.doSomething("A value");
}
}
When I run the test on it's own, everything works fine. If I run either EclEmma or Cobertura with the above test using JMockit 1.9, my code coverage is reported correctly. However, when the test is run using JMockit 1.10 and a code coverage tool such as EclEmma or Cobertura I end up with a LinkageError being reported like this one:
FAILED: should_test_something(javax.persistence.$Impl_EntityManager@77ea08e7)
java.lang.LinkageError: loader (instance of sun/misc/Launcher$AppClassLoader): attempted duplicate class definition for name: "my/pkg/TestMyBean$1"
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:800)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:449)
at java.net.URLClassLoader.access$100(URLClassLoader.java:71)
at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
at my.pkg.TestMyBean.should_test_something(TestMyBean.java:22)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.lang.reflect.Method.invoke(Method.java:606)
This test used to work with JMockit 1.8, stopped working with JMockit 1.9
public class InetAddressTest {
@Injectable
private InetAddress mockInetAddress;
@Test
public void testInetAddressMock() throws Exception{
new NonStrictExpectations(InetAddress.class) {{
InetAddress.getLocalHost();
result = mockInetAddress;
}};
Assert.assertSame(InetAddress.getLocalHost(), mockInetAddress);
}
}
The problem here is that JMockit complains about the class being already mocked.
Class is already mocked: class java.net.InetAddress
This is fair enough, but what is the recommended approach when I need to mock a static method from a class while having an Injectable
value as well?
Refer to:
https://code.google.com/p/jmockit/issues/detail?id=311
This happens again for Java 6...
Currently, when recording or verifying an expectation on a specific element of a mocked enum, it is necessary to use "onInstance(EnumType.A_VALUE)" to match only that enum element. This should be unnecessary, with onInstance matching being applied automatically for enums.
Sometimes a user will write a "result = new SomeClass(someMock)" recording, where the called constructor happens to make calls on "someMock". Such indirect recordings are unintended, and can result in confusing exceptions.
Such misuses of the mocking API should be detected, with a helpful exception message shown.
Currently, when mocking a Java 8 interface which happens to contain default methods, they are not mocked.
There are two cases:
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.