We have an import problem with Eclipse :
the test class uses Assertions.assertThat
When hitting Ctrl + Shift + O to organize the imports, Eclipse replace Assertions.assertThat with StrictAssertions.assertThat
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.Test;
public class TheTest {
#Test
public void testName() {
assertThat(2).isEqualTo(2);
}
}
is replaced with :
import static org.assertj.core.api.StrictAssertions.assertThat; // change here !
import org.junit.Test;
public class TheTest {
#Test
public void testName() {
assertThat(2).isEqualTo(2);
}
}
And when we have some specific asserts that are only in Assertions (for lists), Eclipse add StrictAssertions to the imports.
import static org.assertj.core.api.Assertions.assertThat;
import java.util.ArrayList;
import org.junit.Test;
public class TheTest {
#Test
public void testName() {
assertThat(2).isEqualTo(2);
assertThat(new ArrayList<>()).isEmpty();
}
}
is changed to :
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.StrictAssertions.assertThat; // this import was added
import java.util.ArrayList;
import org.junit.Test;
public class TheTest {
#Test
public void testName() {
assertThat(2).isEqualTo(2);
assertThat(new ArrayList<>()).isEmpty();
}
}
It seems that Assertions extends StrictAssertions, so their is no problem using StrictAssertions, but why is Eclipse not using the extended class ?
Looks like, because assertThat(int actual) is defined in StrictAssertions and not hidden by Assertions, Eclipse decides to import from StrictAssertions.
Also, for organizing imports Eclipse seems to ignore Type Filters - so even that won't help.
It seems that Assertions extends StrictAssertions, so their is no problem using StrictAssertions
Not for your current setup, but StrictAssertions has been removed with AssertJ 3.2.0. So when upgrading to a newer version of AssertJ StrictAssertions will get in your way.
I'd suggest you upgrade to 3.2.0 or later, if it is possible with your project.
Related
Why do I get a NullPointerExeption for testManuscript when trying to run my test?
This is my Manuscript.java:
package org.lhoffjann;
public class Manuscript {
private String msID;
private String path;
public void setMSid(String msID){
this.msID = msID;
}
public String getMSid() {
return this.msID;
}
}
This is my ManuscriptTest.java:
package org.lhoffjann;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class ManuscriptTest {
private static Manuscript testManuscript;
#Before
public void setUp(){
testManuscript = new Manuscript();
}
#Test
public void testGetMSid() {
testManuscript.setMSid("1234");
assertTrue("1234" == testManuscript.getMSid());
}
}
You have imported #Test from JUnit 5, while you're using #Before from JUnit 4, that combination doesn't work. You need to choose which JUnit version you want to use, 4 or 5, and then consistently import classes from that JUnit version. I would recommend using JUnit 5, and removing all JUnit 4 dependencies from your classpath, or at least configure your IDE to not suggest those imports.
For this specific case, replace #Before (org.junit.Before) with #BeforeEach (org.junit.jupiter.api.BeforeEach).
In the example as shown, you don't even need this setUp method, as each test-execution gets its own instance of the test class. You can use:
private Manuscript testManuscript = new Manuscript();
That is, remove static, initialize the field directly, and remove the setUp method.
Even if you continue to use the setUp method, I recommend removing the static, so testManuscript is an instance field, like it is actually used.
You have mixed Junit4 with Junit5. You should use only one version.
Junit4 or
package org.lhoffjann;
import org.junit.Before;
import org.junit.Test;
import org.junit.Assert;
public class ManuscriptTest {
private static Manuscript testManuscript;
#Before
public void setUp(){
testManuscript = new Manuscript();
}
#Test
public void testGetMSid() {
testManuscript.setMSid("1234");
Assert.assertEquals("1234",testManuscript.getMSid());
}
or
Junit5
package org.lhoffjann;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
class ManuscriptTest {
private static Manuscript testManuscript;
#BeforeEach
public void setUp() {
testManuscript = new Manuscript();
}
#Test
void testGetMSid() {
testManuscript.setMSid("1234");
Assertions.assertEquals("1234", testManuscript.getMSid());
}
}
I have a class where I'm using Powermock + Mockito to suppress a static method in a utility class. It works fine with Powermock 1.6.2 and Mockito 1.10.19, but I've been tasked with moving to Java 10 (JRE: we're still compiling with Java 8) and so I've moved to Powermock 2 (currently in beta) and Mockito 2.16.1. Now, I consistently get org.mockito.exceptions.misusing.InvalidUseOfMatchersException:
Misplaced or misused argument matcher detected here.
A simple example, MyMockito.java:
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import java.lang.reflect.Method;
import static org.mockito.Mockito.any;
import static org.powermock.api.mockito.PowerMockito.spy;
import static org.powermock.api.mockito.PowerMockito.when;
import static org.powermock.api.support.membermodification.MemberMatcher.method;
import static org.powermock.api.support.membermodification.MemberModifier.suppress;
#RunWith(PowerMockRunner.class)
#PrepareForTest(StringMeasurer.class)
public class MyMockito {
#Test
public void testSuppressMethod() throws Exception {
spy(StringMeasurer.class);
Method measure = method(StringMeasurer.class, "measure", String.class);
suppress(measure);
when(StringMeasurer.class, measure)
.withArguments(any(String.class))
.thenReturn(10);
System.out.println(StringMeasurer.measure("Hello"));
}
And StringMeasurer.java:
public class StringMeasurer {
private StringMeasurer() {}
public static int measure(String s) {
return s.length();
}
}
}
I'm assuming that either there have been some changes to how matchers can be used to match arguments in stubbed static methods, or else this should never have worked and somehow got through in Mockito 2 (or possibly this is a bug in the Powermock beta). Can anyone provide me some insight into what I'm doing wrong?
Working solution for PowerMock 2.0.0-beta.5:
import static org.mockito.ArgumentMatchers.any;
import static org.powermock.api.mockito.PowerMockito.when;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
#RunWith(PowerMockRunner.class)
#PrepareForTest(StringMeasurer.class)
public class MyMockito {
#Test
public void testSuppressMethod() throws Exception {
PowerMockito.mockStatic(StringMeasurer.class);
when(StringMeasurer.measure(any(String.class))).thenReturn(10);
System.out.println(StringMeasurer.measure("Hello"));
}
}
More details can be found in the official PowerMock documentation: Mocking Static Method
The question uses the PowerMockito.spy() method, which is required for partial mocking, although the example given only has one static method, so that's not necessary here. Here's a working solution that uses partial mocking for an extended example:
MyMockito.java:
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import java.lang.reflect.Method;
import java.util.List;
import static junit.framework.Assert.assertEquals;
import static org.mockito.Mockito.*;
import static org.powermock.api.support.membermodification.MemberMatcher.method;
import static org.powermock.api.mockito.PowerMockito.doReturn;
import static org.powermock.api.mockito.PowerMockito.spy;
#RunWith(PowerMockRunner.class)
#PrepareForTest(StringMeasurer.class)
public class MyMockito {
#Test
public void testSuppressMethod() throws Exception {
spy(StringMeasurer.class);
Method measure = method(StringMeasurer.class, "measure", String.class);
doReturn(10).when(StringMeasurer.class, measure)
.withArguments(any(String.class));
System.out.println(StringMeasurer.measure("Hello"));
List<String> dummy = StringMeasurer.dummy(5);
assertEquals(5, dummy.size());
dummy.forEach(System.out::println);
}
}
And StringMeasurer.java:
import java.util.ArrayList;
import java.util.List;
public class StringMeasurer {
private StringMeasurer() {}
public static int measure(String s) {
return s.length();
}
public static List<String> dummy(int size) {
List<String> list = new ArrayList<>();
for (int i = 0; i < size; i++) {
list.add("" + i);
}
return list;
}
}
Note that, in this case, the accepted solution would mock the StringMeasurer.dummy() method as well, returning an empty list, and the test would fail on the assertEquals().
Is it a bug of Powermock or I'm doing sth wrong?
The following test should pass, but failed with:
trackBugPartialMockCountMore(com.xiaomi.finddevice.test.testcase.PowerMockBug)
org.mockito.exceptions.verification.TooManyActualInvocations:
classToMock.foo();
Wanted 1 time:
-> at com.xiaomi.finddevice.test.testcase.PowerMockBug.trackBugPartialMockCountMore(PowerMockBug.java:24)
But was 3 times. Undesired invocation:
-> at com.xiaomi.finddevice.test.testcase.PowerMockBug.trackBugPartialMockCountMore(PowerMockBug.java:22)
When I remove #PrepareForTest(ClassToMock.class), every thing goes well and the test get passed.
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import static org.mockito.Mockito.verify;
import static org.powermock.api.mockito.PowerMockito.mock;
import static org.powermock.api.mockito.PowerMockito.when;
#RunWith(PowerMockRunner.class)
#PrepareForTest(ClassToMock.class)
public class PowerMockBug {
#Test
public void trackBugPartialMockCountMore() {
ClassToMock mock = mock(ClassToMock.class);
when(mock.foo()).thenCallRealMethod();
mock.foo();
verify(mock).foo();
}
}
class ClassToMock {
public int foo() { return 0x10; }
}
VERSION: powermock-mockito-junit-1.6.3
In your example you don't need to use PowerMock because you are not mocking/spying a final or static method. You can safely remove both #RunWith and #PrepareForTest annotations. Only mockito is needed for your purposes
I am trying to have RunWith(PowerMockRunner.class) working with my existing package annotation.
Versions:
powermock 1.4.12 mockito 1.9.0 junit 4.8.2
package-info.java // this is for the package annotation
#TestAnnotation(version="1.0")
package com.smin.dummy;
TestAnnotation.java // this is the the metadata annotation class for package "com.smin.dummy"
package com.smin.dummy;
import java.lang.annotation.*;
#Retention(RetentionPolicy.RUNTIME)
#Target(ElementType.PACKAGE)
public #interface TestAnnotation {
String version();
}
A.java
package com.smin.dummy;
public class A {
private static Package myPackage;
private static TestAnnotation version;
static {
myPackage = TestAnnotation.class.getPackage();
version = myPackage.getAnnotation(TestAnnotation.class);
}
public static String getVersion() {
return version.version();
}
}
MockA.java
package com.smin.dummy;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import com.smin.dummy.A;
#RunWith(PowerMockRunner.class) //comment out this line to see the difference
#PrepareForTest(A.class)
public class MockA {
#Test
public void test_mocked() throws Throwable {
String thisVersion = A.getVersion();
System.out.println(thisVersion);
}
}
In the unitest MockA.java, if I don't use RunWith(PowerMockRunner.class), I will get the thisVersion printed 0.1 as expected. But after adding RunWith(PowerMockRunner.class), thisVersion turns into null. I suspect PowerMockRunner is doing some funny thing with the package annotation here, anybody has any idea? see the mini version of my code below:
Building on #Alban's sleuthing in the comments, it looks like adding this annotation to your test case should circumvent the problem:
#PowerMockIgnore("com.smin.dummy.TestAnnotation")
I have some simple classes I'm using to see if I can get powermock to work:
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.easymock.PowerMock;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
#RunWith(PowerMockRunner.class)
#PrepareForTest(Foo.class)
public class FooTest
{
#Test
public void testFoobar(){
Foo test = PowerMock.createPartialMock(Foo.class, "foobar");
PowerMock.replay(test);
}
}
and
public class Foo
{
public String foobar(String aString){
return aString + " blah";
}
}
When I try to run this unit test, it tells me:
java.lang.NoClassDefFoundError: org/easymock/classextension/internal/ClassProxyFactory$MockMethodInterceptor
...
I have no idea why its doing this. Please help.
Make sure you're including EasyMock in your class path when using PowerMock... you can find the download page here.
According to the Wiki on PowerMock, it states that EasyMock is a dependency.