Junit4 + Spring 2.5 : Asserts throw "NoClassDefFoundError" - java

I've been coding tests in Junit4 with Spring, and I got this funny behavior:
If my tests are passing like this, everything is fine:
#Test
public void truthTest(){
assertTrue(true); //Ok
}
But, if my test fails:
#Test
public void truthTest(){
assertTrue(false); //ERROR
}
Then instead of a test failure I receive an ugly and cryptic stack trace, This is it:
http://pastie.org/429912
Sorry for this ugly dump, but its the only data I've got to explain the problem (I "pastied" it for readability)
I'm really puzzled, has anyone encountered this kind of problem before? Thanks in advance!

http://jira.springframework.org/browse/SPR-5145
It is an known issue with spring-test 2.5.x. It is incompatible with JUnit 4.5. Use 4.0-4.4.
Or you can try the patch in the issue tracker.

I had the same problem when I wrote my Spring JUnit tests. Like a lot of posts available online, there are only two alternatives
1) Stay up to date with the Spring version and use the latest version of JUnit
or
2) Leave your current Spring version and use JUnit version 4.4 or less.
I chose the option # 2 where we left our Spring version at 2.5 and downloaded JUnit 4.4. Everything worked fine after that.
Also another point to be aware of is that if your project i.e., the project A you are writing your tests in has a dependency on another project B that has another version of Spring, you would get a similar error too. I learnt it the hard way.
-Prashanth

What if you imported AssumptionViolatedException into your test class?
It looks like it can't find the class to throw the appropriate exception.

Related

How to migrate an Eclipse AspectJ project to IntelliJ IDEA

At my company, we are currently working with Eclipse for our Java projects.
As me and some other coworkers would rather use IntelliJ, we took a crack at migrating our projects and failed at getting AspectJ to work.
We are using Java 7 though the projects are written in Java 6 compatility.
Before trying it out we updated to the most recent version of IDEA (14.03).
The AspectJ version is 1.7.3.
Here are the steps we took:
import the project and dependencies into IntelliJ
download and install AspectJ
Under Settings -> Java Compiler: Use ajc compiler, delegate to javac (path to aspectjtools.jar is correct as the test button indicates)
Add AspectJ libs to Global Libraries (aspectjrt.jar, aspectjtools.jar, aspectjweaver.jar, and org.aspectj.matcher.jar)
Create AspectJ facet for the one module that is using AspectJ, leave all settings as is (no aspect path defined)
Add aspectjrt to project libraries
rebuild, make etc.
LogContext is just an empty interface. Classes that want a logger appended implement this interface.
This method is injected with AspectJ. Unfortunately I am not an expert with this and the guy who implemented it left the company, so I am stuck.
In order to check general functionality, we implemented a tiny project from scratch with just three classes with the same settings as above:
public interface LogContext {}
public aspect LogContextAspect {
public void LogContext.log() {
System.out.println("Log!");
}
}
public class Aspect implements LogContext {
public static void main(String[] args) {
Aspect aspect = new Aspect();
aspect.log();
}
}
The code actually executes fine and prints out the "Log!" message, but on make I get the following error:
Error:(4, 0) ajc: The type Aspect must implement the inherited abstract method LogContext.log()
What are we missing here? In order to migrate our projects, we need AspectJ to work.
The whole system is built with Java 6 compatibility but runs on Java 7.
Thanks for your help!
Sascha
I tried with IDEA 14.1.1 Ultimate and it works nicely, even though AspectJ support in IDEA is generally not as advanced as in Eclipse, even though all in all IDEA to me is superior. But for AspectJ I often use Eclipse.
I think it would be a good idea to "mavenise" your project. This way it would work in Eclipse and IDEA. In IDEA activate auto import for Maven changes to let Maven be the leading system and IDEA just follow its settings. This works well for my AspectJ projects. But in this case I set up your example manually (no Maven). After a few steps it works now. Along the way I did not see the error message you mentioned.
Edit: I use AspectJ 1.8.5, if that makes any difference.
Edit 2: I have tried with both compiler and runtime manually set to 1.7.3, it still works.

java.lang.VerifyError with Mockito 1.10.17

I am trying to replace JMock with Mockito (1.10.17). I have already done some unit tests successfully, but now I want to use the timeout feature
verify(publisher, timeout(5000)).notifySubscribers(any(BecameMasterMessage.class));
and I get this exception:
java.lang.VerifyError: (class: org/mockito/internal/verification/VerificationOverTimeImpl, method: verify signature: (Lorg/mockito/internal/verification/api/VerificationData;)V) Incompatible argument to function
at org.mockito.verification.Timeout.<init>(Timeout.java:32)
at org.mockito.verification.Timeout.<init>(Timeout.java:25)
at org.mockito.Mockito.timeout(Mockito.java:2164)
The issue happens in IntelliJ and with Maven. There is only 1 version of Mockito on the classpath. There is also JMock 2.5.1 on the classpath which I cannot remove since 99% of my unit tests still use JMock at this moment. I don't know if that has anything to do with it.
UPDATE: I tried with JMock 2.6.0 and Hamcrest 1.3 but the result is the same.
UPDATE 2:
This works:
Thread.sleep( 5000 );
verify( m_publisher ).notifySubscribers( any( BecameMasterMessage.class ) );
And this does not:
verify(publisher, timeout(5000)).notifySubscribers(any(BecameMasterMessage.class));
UPDATE 3:
I have made a small test project that has the exact same problem: See https://github.com/wimdeblauwe/mockito-verify-problem and run it from IntelliJ or with Maven.
The problem here is an unfortunate constellation between TestNG, JUnit and Mockto. To fix your issue, you just need to add a dependency to JUnit 4.0 or greater (the most recent version is currently 4.12):
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
Here are the details:
TestNG, which is apparently your testing framework, declares a dependency to the quite old JUnit version 3.8.1. Mockito does not declare a dependency to JUnit at all but it uses some JUnit classes that were introduced in JUnit 4.0 (!).
Edit:
The method Mockito#timeout() in your example creates a Timeout instance which in turn creates an instance of VerificationOverTimeImpl. The method VerificationOverTimeImpl#verify() handles an error of type ArgumentsAreDifferent which is a subclass of org.junit.ComparisonFailure.
From JUnit version 3.8.1 to 4.x the class hierarchy of ComparisonFailure changed to having AssertionError instead of Error as base class. The VerifiyError is caused because VerificationOverTimeImpl#handleVerifyException() requires an AssertionError but would be invoked with an Error when JUnit 3.8.1 is used.
EDIT: It seems stefan answered first. His diagnostic is almost correct, however, org.mockito.exceptions.verification.junit.ArgumentsAreDifferent do extends junit.framework.ComparisonFailure, that is present in JUnit 3.x and it is a dependency of TestNG 5.x.
The VerifyError itself has probably something to do when the JVM is performing the linking as there is changes in the ComparisonFailure type itself between JUnit 3.x and JUnit 4.x.
Anyway the issue in Mockito is that it uses a JUnit class where it shouldn't. And that Mockito don't support anymore JUnit 3.x.
tl;tr
We have an issue in the code internally the verification mode you are using use a JUnit class, that is not on the classpath. Adding JUnit in the dependency of your POM will fix things.
Thanks for reporting. I've created an issue on GitHub (#152)
long story
For some reason TestNG 5.xxx make the JVM fail with a VerifyError, on a method that is not even called at that point.
java.lang.VerifyError: (class: org/mockito/internal/verification/VerificationOverTimeImpl, method: verify signature:
(Lorg/mockito/internal/verification/api/VerificationData;)V) Incompatible argument to function
But switching to the latest version of TestNG, 6.8.something make the JVM fail with an understandable cause : NoClassDefFoundError
java.lang.NoClassDefFoundError: junit/framework/ComparisonFailure
Which points to the real issue here, now there's only to find which class depends on JUnit. This class is ArgumentsAreDifferent which extends junit.framework.ComparisonFailure, this exception appears in a try/catch block in VerificationOverTimeImpl that is needed for the timeout verification.
This issue has been there probably since 1.10.x when fixing some timeout issues.
Note I copied this answer on the mailing list as well.

Gradle + TestNG only runs certain tests as single tests

I've been using Gradle + TestNG + Java + Selenium for my web UI tests for quite a while now and I've only recently run in to this issue. For some reason when I try to run a single test class using -DtaskName.single=ExampleTestClass where ExampleTestClass would be ExampleTestClass.java it only works on some of my test classes.
I'm getting the error: Could not find a matching test for pattern: ExampleTestClass
I've seen this error in the past due to typos or missing #Test annotations etc, so I'm familiar with the "normal" cause, but this is quite bizarre as it appears to work on some test classes and not others. I've inspected the code and all annotations and groups are in place for the test methods, they run fine from my IDE (IntelliJ), and they are all located in the same directory / package path. Is there something I'm missing here? I don't know if I'm seeing things but I did notice that it didn't work with a test class that did not have Test as the last four characters of the Java class name but upon renaming it, still no dice. I've read the documentation and can't find anything wrong. Is there anything else that may be causing this to fail? It's quite odd since these tests are all so similar in every way. I even checked character encoding etc - no discrepancies between any of them.
Any advice or ideas on where to look next would be great.
Cheers,
Darwin
I ran into the exact same thing with gradle 1.6 (haven't had time to upgrade), and TestNG. A single test in a project with multiple tests get skipped and also gradle complains about not finding it if you try running the single test alone. Debug run shows the missing test .class file being found by gradle.
I worked around it by adding an #Test annotation to the test class in addition to the test method. That seems to make gradle find it.
I recently ran into a similar issue. I tried to run a test with -DTest.single and --tests but it wasn't found. After a bit of frustration I realized that the test was in a test group that was excluded in my test task configuration. I had incorrectly assumed that running with -Dtest.single would overrule exclusions, including that test's group allowed it to run as a single test.

not all junit tests are running in eclipse

I have a java project in eclipse, when I press the project right click -> run as junit some tests do not run. I attached a picture, see YamiMailSenderTest for example.
When I try to run the tests directly they are running.
I am using eclipse 3.7.2.
and expanded view:
Any idea?
Ran into the same problem, my error was that I wrote: public void myMethodName(){ //assertions }
instead of: public void testMyMethodName() { //assertions }
the test before the MyMethodName is important.
It's a bit late, but in case anyone finds this via a search engine:
If a Test is run multiple times the results provided by JUnit are indistinguishable for those Tests and thus the results are only displayed for one run. See also the following Eclipse bug report: https://bugs.eclipse.org/bugs/show_bug.cgi?id=172256
Check if you are excluding tests from run by attributes and check under Run > Run Configurations if your JUnit configuration are excluding any tests.
In jUnit 4, a test case needs to have #Test annotation. The test case can be set to ignore with #Ignore annotation. The whole test class can also be set to ignore by placing the #Ignore annotation right above the class declaration. Note: In jUnit 4 , there is no need to extend Testcase class as in jUnit 3. Everything is in annotation.
I have no idea about jUnit 3 since I use only 4.
I had a similar problem. For some reason, the "Run As -> jUnit Test" was always skiping the first test package. I was on an older version of Eclipse and SpringSource.
I moved back to Juno - Version: 4.2.1 and all my test run when I perform: "Run As -> jUnit Test. "
I had the same problem. Eclipse would only recognize and run 5 out of my 9 tests. After much troubleshooting I found this trick to convince Eclipse to recognize the remaining tests: just open each file, hit space and then backspace to mark it as changed, and save it. Then, Eclipse will recognize it as a test.

JUnit throws java.lang.NoSuchMethodError For com.google.common.collect.Iterables.tryFind

I am using Google Guava v13.0 but when I run a JUnit test with code containing tryFind, I get this message:
java.lang.NoSuchMethodError: com.google.common.collect.Iterables.tryFind(Ljava/lang/Iterable;Lcom/google/common/base/Predicate;)Lcom/google/common/base/Optional;
This only seems to happen with JUnit tests as when the production code runs there are no problems. I am using Intellij IDEA v11.1.3 and can navigate into the guava JAR file to find tryFind in the com.google.common.collect.Iterable.class.
I've seen similar posts, but I'm not sure how this relates to JUnit. Any ideas on what my issue might be?
This sort of error is usually caused by having an older version of Guava (or even google-collections) on the classpath in addition to the newer version you're trying to use. Try to check what's on the classpath when running your test.
Go with Colin's answer, here's a nice way to detect where the stuff is loaded:
System.out.println(
Iterables.class.getProtectionDomain().getCodeSource().getLocation()
);
This should print out the path to the guava (or g-c) version you are using.

Categories