This is the test:
import static junit.framework.Assert.assertTrue;
import static org.powermock.api.mockito.PowerMockito.mock;
import static org.powermock.api.mockito.PowerMockito.whenNew;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
#RunWith(PowerMockRunner.class)
#PrepareForTest( {ClassUnderTesting.class} )
public class ClassUnderTestingTest {
#Test
public void shouldInitializeMocks() throws Exception {
CollaboratorToBeMocked mockedCollaborator = mock(CollaboratorToBeMocked.class);
suppress(constructor(CollaboratorToBeMocked.class, InjectedIntoCollaborator.class));
whenNew(CollaboratorToBeMocked.class)
.withArguments(InjectedAsTypeIntoCollaborator.class)
.thenReturn(mockedCollaborator);
new ClassUnderTesting().methodUnderTesting();
assertTrue(true);
}
}
These are the classes :
public class ClassUnderTesting {
public void methodUnderTesting() {
new CollaboratorToBeMocked(InjectedAsTypeIntoCollaborator.class);
}
}
public class CollaboratorToBeMocked {
public CollaboratorToBeMocked(Class<InjectedAsTypeIntoCollaborator> clazz) {
}
public CollaboratorToBeMocked(InjectedIntoCollaborator someCollaborator) {
}
public CollaboratorToBeMocked() {
}
}
public class InjectedAsTypeIntoCollaborator {
}
public class InjectedIntoCollaborator {
}
This is the error :
org.powermock.reflect.exceptions.TooManyConstructorsFoundException: Several matching constructors found, please specify the argument parameter types so that PowerMock can determine which method you're refering to.
Matching constructors in class CollaboratorToBeMocked were:
CollaboratorToBeMocked( InjectedIntoCollaborator.class )
CollaboratorToBeMocked( java.lang.Class.class )
Here comes the question: how can I make PowerMock figure out what constructor to look for?
The problematic line is the suppress. That is where the error comes from.
Perhaps it is too late for your question. I met it today and found the solution at the following url. Basically, you need to specify your argument type like.
whenNew(MimeMessage.class).**withParameterTypes(MyParameterType.class)**.withArguments(isA(MyParameter.class)).thenReturn(mimeMessageMock);
http://groups.google.com/group/powermock/msg/347f6ef1fb34d946?pli=1
Hope it can help you. :)
I didn't know of PowerMock until you wrote your question, but did some reading and found this in their documentation. Still I am not really sure if that helps you:
If the super class have several
constructors it's possible to tell
PowerMock to only suppress a specific
one. Let's say you have a class called
ClassWithSeveralConstructors that has
one constructor that takes a String
and another constructor that takes an
int as an argument and you only want
to suppress the String constructor.
You can do this using the
suppress(constructor(ClassWithSeveralConstructors.class, String.class));
method.
found at http://code.google.com/p/powermock/wiki/SuppressUnwantedBehavior
Isn't it the thing you wanted?
EDIT: Now I see, you've already tried suppressing. But are you sure you got the suppress call right? Isn't the first argument of constructor() supposed to be the class you would like to surpress the constructor in?
If using PowerMock for EasyMock you can do PowerMock.expectNew(CollaboratorToBeMocked.class, new Class[]{InjectedIntoCollaborator.class}, ...) where the Class[] is the parameter types of the constructor you're expecting to be called. This will resolve the ambiguity between the constructors.
Related
How does the java accessibility (or perhaps, scope) work with respect to type import multi-level nested classes? An example:
ClassA.java:
package com.oracle.javatests;
public class ClassA {
public static class NestedAA {
public void printSomething() {
System.out.println("inside " + this.getClass().getName());
}
public static class NestedAB{
public void printSomethingAB() {
System.out.println("inside " + this.getClass().getName());
}
}
}
public void printSomething() {
System.out.println("inside " + this.getClass().getName());
}
}
Main.java
package com.oracle.javatests;
import com.oracle.javatests.ClassA.*;
// import com.oracle.javatests.ClassA.NestedAA.*; // Adding this will resolve NestedAB
public class Main {
public static void main (String[] args){
ClassA objA = new ClassA();
objA.printSomething();
NestedAA nestedAA = new NestedAA(); // Ok
NestedAB nestedAB = new NestedAB(); // Compiler error- NestedAB cannot be resolved to a type
}
}
The import statement does not import NestedAB type when using wildcards. A perhaps similar question led me to the java spec sheet which clarifies Type-Import-on-Demand Declarations :
A type-import-on-demand declaration allows all accessible types of a
named package or type to be imported as needed.
The accepted answer to the question implies that the on demand import declarations are not recursive. The reasoning is perhaps what Java considers "all accessible types of a named type", and the general concept of packages but I am falling short of connecting the dots and understand what accessible types means with respect to nested classes.
Can please anyone help explain how the type import and accessibility seem to work in java (while ignoring the arguable use of wildcard imports)
It's not heard to understand. import static com.foo.bar.*; is the exact same thing as import static com.foo.bar.[everything you can imagine here but without dots].
In other words, in your example, with import static pkg.ClassA.*; you can just write NestedAA without qualifiers and that works, because import static pkg.ClassA.NestedAA; would have made that work just the same.
You cannot write NestedAB unqualified and expect that to work; there is nothing you could possibly write instead of a * (which doesn't include dots) that would make that work, therefore, a star import doesn't make it work either.
I am getting an issue using powermockito (2.0.0-beta5) to verify a static method was called a certain number of times when I call a different (also static) method. The classes are prepared for test at the top of my test file The relevant code snippet is:
mockStatic(Tester.class);
when(Tester.staticMethod(anyString(), anyString())).thenAnswer(new FirstResponseWithText());
OtherClass.methodThatCallsTesterStaticMethod("", "", "", false, "");
verifyStatic(Tester.class, times(3));
Tester.sendFaqRequest(anyString(), anyString());
FirstResponseWithText is a class that extends Answer that controls the order of responses. I've used that elsewhere and it works fine.
I get the following error on the verifyStatic line:
org.mockito.exceptions.misusing.NotAMockException:
Argument passed to verify() is of type Class and is not a mock!
Make sure you place the parenthesis correctly!
See the examples of correct verifications:
verify(mock).someMethod();
verify(mock, times(10)).someMethod();
verify(mock, atLeastOnce()).someMethod();
What is the proper way to pass the class to verifyStatic? All the examples I can find online are for pre-2.x.x releases where verifyStatic did not take a class parameter.
I think the PowerMockito version is not the problem. I tested the following code with versions
1.7.3,
2.0.0-beta.5 (your version),
2.0.2.
Application classes:
package de.scrum_master.stackoverflow.q52952222;
public class Tester {
public static String sendFaqRequest(String one, String two) {
return "real response";
}
}
package de.scrum_master.stackoverflow.q52952222;
public class OtherClass {
public static void methodThatCallsTesterStaticMethod(String one, String two, String three, boolean four, String five) {
System.out.println(Tester.sendFaqRequest("A", "B"));
System.out.println(Tester.sendFaqRequest("C", "D"));
System.out.println(Tester.sendFaqRequest("E", "F"));
}
}
Test classes:
package de.scrum_master.stackoverflow.q52952222;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import java.util.Arrays;
public class FirstResponseWithText implements Answer {
#Override
public Object answer(InvocationOnMock invocation) throws Throwable {
Object[] args = invocation.getArguments();
String methodName = invocation.getMethod().getName();
return methodName + " called with arguments: " + Arrays.toString(args);
}
}
package de.scrum_master.stackoverflow.q52952222;
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.anyString;
import static org.mockito.Mockito.times;
import static org.powermock.api.mockito.PowerMockito.*;
#RunWith(PowerMockRunner.class)
#PrepareForTest({ Tester.class })
public class MyTest {
#Test
public void myTest() {
// Tell PowerMockito that we want to mock static methods in this class
mockStatic(Tester.class);
// Stub return value for static method call
when(Tester.sendFaqRequest(anyString(), anyString())).thenAnswer(new FirstResponseWithText());
// Call method which calls our static method 3x
OtherClass.methodThatCallsTesterStaticMethod("", "", "", false, "");
// Verify that Tester.sendFaqRequest was called 3x
verifyStatic(Tester.class, times(3));
Tester.sendFaqRequest(anyString(), anyString());
}
}
So if this does not work for you and your Maven or Gradle dependencies are also okay, the difference is maybe in your FirstResponseWithText class. Maybe you want to show it so we can all see what kind of magic you do in there. As you can see from my sample code, I had to make several educated guesses because you only share a little snippet of test code and not MCVE like you should. This way I can only speculate and actually I do not like to because it might be a waste of time for both you and myself.
I'm testing a class and wanted to monitor calls to a specific method, namely to save the calling parameters for later analysis.
Testing is done with EasyMock, so it was logical to use EasyMock.capture feature. However, the examples that I managed to find do not work for me - I get the following compile error at the line with capture:
expect(T) in EasyMock cannot be applied to (void)
reason: no instance of type variable T exist so that void conforms to T
It would be great if somebody could point out my mistake(s) for me. Below is a code snippet:
import static org.easymock.EasyMock.capture;
import org.easymock.Capture;
import org.easymock.CaptureType;
import org.easymock.EasyMock;
import org.junit.Before;
class B {
}
class A {
public void doSomething(B input) {
}
}
public class ATest {
private Capture<B> capturedData;
private A testObject;
#Before
private void setUp() {
capturedData = EasyMock.newCapture(CaptureType.ALL);
testObject = EasyMock.createNiceMock(A.class);
EasyMock
.expect(testObject.doSomething(capture(capturedData)))
.anyTimes();
}
}
Thanks a lot in advance!
Your problem is not related to the capture, but to the return type of your doSomething() method:
Since A.doSomething(B input) is of return type void, you don't expect the method to return anything, thus you cannot use EasyMock.expect() for it. Instead, simply invoke the method and use EasyMock.expectLastCall(), like so:
testObject.doSomething(capture(capturedData));
EasyMock.expectLastCall().anyTimes();
EasyMock.expectLastCall() declares that you expect the last method invocation before expectLastCall() to be executed. You can then handle it just like expect(), e.g. add anyTimes() to it.
I am attempting to test a method that creates a new instance of another class that I wish to mock using powermock. My code (simplified) is as follows -
Testing code:
import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import static org.easymock.EasyMock.anyObject;
import static org.powermock.api.easymock.PowerMock.*;
#RunWith(PowerMockRunner.class)
#PrepareForTest( { ClassUnderTest.class } )
public class TestForClassUnderTest {
private ClassToBeMocked classToBeMocked;
private ClassUnderTest classUnderTest;
public void testSimple() throws Exception {
classToBeMocked = createMock(ClassToBeMocked.class);
// trying to intercept the constructor
// I *think* this is the root cause of the issue
expectNew(ClassToBeMocked.class, anyObject(), anyObject(), anyObject()).andReturn(classToBeMocked);
classToBeMocked.close();
expectLastCall();
replayAll();
// call to perform the test
classUnderTest.doStuff();
}
}
Code that is being tested:
import ClassToBeMocked;
public class ClassUnderTest {
private ClassToBeMocked classToBeMocked;
public void doStuff() {
classToBeMocked = new ClassToBeMocked("A","B","C");
// doing lots of other things here that I feel are irrelevant
classToBeMocked.close();
}
}
Code that I wish to mock:
public class ClassToBeMocked {
public ClassToBeMocked(String A, String B, String C) {
// irrelevant
}
public close() {
// irrelevant
}
}
The error I get is as below:
java.lang.ExceptionInInitializerError
at ....more inner details of where this goes into
at ClassToBeMocked.close
at ClassUnderTest.doStuff
at TestForClassUnderTest.test.unit.testSimple
Caused by: java.lang.NullPointerException
PowerMock version:1.4.5
EasyMock version: 3.1
PS: I have stripped down the code to bare minimums, only showing the details of the mocking library, let me know if you think my other code is somehow interfering and I can give more details on the bits you think are important to show. Any links to other examples doing this may even help.
I realized that the reason this wasn't working was because I was extending another class. I had
#RunWith(PowerMockRunner.class)
#PrepareForTest( { ClassUnderTest.class } )
public class TestForClassUnderTest extends AnotherClass {
}
as soon as I removed the extends, it worked. Not sure if its just not able to extend another class with powermock or due to AnotherClass, but removing it worked for me
whenever you wish to mock a new instance of any class, you should be doing like this
Powermock.expectNew(ClassYouWishToMock.class).andReturn(whateverYouWantToReturn).anyTimes();
Powermock.replayAll();
this will return 'whateverYouWantToReturn' whener new is called on this class.
but whenever you want to mock a instance variable, you should be using Whitebox feature of easymock.
have a look at following Example
Class A{
private B b;
}
to mock this my test class will look something like this
...//other powermock, easymock class level annotations
#PrepareForTest(B.class)
class ATest{
Whitebox.setInternalState(B.class,b,whateverValueYouWantYourMockedObjectToReflect);
}
here 'b' passed in parameter, is the variable name you want to mock.
Good Luck!
I started a "for fun, nobody knows, nobody cares" open source project (LinkSet).
In one place I need to get an annotated method of a class.
Is there a more efficient way to do it than this? I mean without the need of iterating through every method?
for (final Method method : cls.getDeclaredMethods()) {
final HandlerMethod handler = method.getAnnotation(HandlerMethod.class);
if (handler != null) {
return method;
}
}
Take a look for Reflections (dependencies: Guava and Javassist). It's a library which has already optimized the most of it all. There's a Reflections#getMethodsAnnotatedWith() which suits your functional requirement.
Here's an SSCCE, just copy'n'paste'n'run it.
package com.stackoverflow;
import java.lang.reflect.Method;
import java.util.Set;
import org.reflections.Reflections;
import org.reflections.scanners.MethodAnnotationsScanner;
import org.reflections.util.ClasspathHelper;
import org.reflections.util.ConfigurationBuilder;
public class Test {
#Deprecated
public static void main(String[] args) {
Reflections reflections = new Reflections(new ConfigurationBuilder()
.setUrls(ClasspathHelper.forPackage("com.stackoverflow"))
.setScanners(new MethodAnnotationsScanner()));
Set<Method> methods = reflections.getMethodsAnnotatedWith(Deprecated.class);
System.out.println(methods);
}
}
If you're going to make several calls to this for every class you can create a descriptor like class which does nothing more than cache this type of information. Then when you want to retrieve the information you just look at it's descriptor.
To answer your question:
Class<?> _class = Whatever.class;
Annotation[] annos = _class.getAnnotations();
will return all annotations of a class. What you've done will only return the very first annotation of a method. Like wise:
Annotion[] annos = myMethod.getAnnotations();
returns all the annotations of a given method.
No. But this is not inefficient at all.
For example spring is using the following code:
public static <A extends Annotation> A getAnnotation(
Method method, Class<A> annotationType) {
return BridgeMethodResolver.
findBridgedMethod(method).getAnnotation(annotationType);
}
(where the BridgedMethodResolver is another topic, but it just returns a Method object)
Also, instead of comparing to null, you can check whether an annotation is present with isAnnotationPresent(YourAnnotation.class) (as suggested in the comments below the question)