I have a gradle file
testCompile('junit:junit')
testCompile('org.powermock:powermock-core:1.6.5')
testCompile('org.powermock:powermock-api-mockito:1.6.5')
testCompile('org.powermock:powermock-module-junit4:1.6.5')
And my test file
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
#RunWith(PowerMockRunner.class)
#PrepareForTest(ExperimentService.class)
There seems to be an error with the #RunWith and I have can't seem to find the problem, it just says that '#RunWith' not applicable to method.
What am I doing wrong?
Thanks.
If you see the RunWith.class, target for this annotation is ElementType.Type which means it can only be applied to Class, enum or interface declaration.
#Retention(RetentionPolicy.RUNTIME)
#Target({ElementType.TYPE})
#Inherited
public #interface RunWith {
Class<? extends Runner> value();
}
You cannot apply this annotation over a method.
Oh never mind I found my mistake, it seems that I put the statement within the class.
Related
Want to create annotation which will contain multiple annotations but want to make it more configurable so that it can be more feasible to use in all scenarios
#SpringBootApplication
#ServletComponentScan(basepackages="com.example.commons.traceability")
#ComponentScan(basePackages={
"com.example.commons.security",
"com.example.commons.restTemplate",
"com.example.commons.logging",
})
#Retention(RetentionPolicy.RUNTIME)
#Target(ElementType.TYPE)
public #interface Microservice{
String[] scanBasePackages() default {};
}
I want to use this application in Spring Application file but also want to make the componentScan more configurable so that apart from the default packages other package can also me included in the component scan
#Microservice(scanBasePackages={"com.example.myproject"})
public class MySpringApplciation{
public static void main (final String[] args){
// some code
}
}
so as in the above code if I pass value of scanBasePackages so those packages should also be included in the component scan.
Is there any way to include values of scanBasePackages inside componentScan in custom annotation ?
Annotations on (custom) annotations are called meta-annotations.
In short: you're lucky. While Java does not allow this out of the box, Spring has a special annotation for this sort of thing: #AliasFor.
I had a similar question, and I found the answer here.
And here is a good source.
Specifically in your case, try this:
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.core.annotation.AliasFor;
#SpringBootApplication
#ServletComponentScan(basePackages="com.example.commons.traceability")
#ComponentScan(basePackages={
"com.example.commons.security",
"com.example.commons.restTemplate",
"com.example.commons.logging",
})
#Retention(RetentionPolicy.RUNTIME)
#Target(ElementType.TYPE)
public #interface Microservice{
// >>> TRY THIS <<<
#AliasFor(annotation = ComponentScan.class, attribute = "basePackages")
String[] scanBasePackages() default {};
}
(I myself am less lucky, since I need this sort of thing for reducing my JUnit5 boilerplate annotations, and #AliasFor is only meaningful in Spring.)
According to JSR 308 (Java Type Annotations) it is possible to annotate any type using ElementType.TYPE_USE:
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.*;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
#Target({ TYPE_USE })
#Retention(RUNTIME)
public #interface MyAnnotation {
String value();
}
How to get the annotated value from a function at runtime?
import java.util.function.Consumer;
import org.junit.Assert;
import org.junit.Test;
public class TestFunctionAnnotation {
#Test
public void test() {
Consumer<TestFunctionAnnotation> fun = #MyAnnotation("NoJoke") TestFunctionAnnotation::test;
Assert.assertEquals("NoJoke", fun.getClass().getAnnotatedSuperclass().getAnnotation(MyAnnotation.class));
// expected:<NoJoke> but was:<null>
}
}
Your #MyAnnotation doesn't appear on the class, or the method, but on the use of the type - something that you can't reflect on. Instead, you'd need a hypothetical "reflection" which could examine the code itself, not just the structure of the types.
Instead, you want to either build a compiler plugin which can read that, or add a task listener inside an annotation processor - see https://stackoverflow.com/a/55288602/860630 for some discussion on this. Once you've done that and can read the annotation, you can generate new code which you could then access at runtime, and do whatever it is you are after here.
I'm working on my first project with Spring and Hibernate and I would like to create a validator for an IP address.
To create the project I use IntelliJ. When I enter the code like this I get an error on the #Target annotation Attribute value must be a class literal
I do understand what this annotation has to do, but if I keep getting this error, it won't work.
I have looked at the documentation about custom constraints here http://docs.jboss.org/hibernate/validator/5.0/reference/en-US/html_single/#validator-customconstraints-simple and I have looked at several Stackoverflow pages, but I can't get this error solved.
import org.hibernate.annotations.Target;
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import static java.lang.annotation.ElementType.FIELD;
/**
* Created by johan on 17-5-17.
*/
#Target({ FIELD })
#Retention(RetentionPolicy.RUNTIME)
#Documented
#Constraint(validatedBy = IpAddressValidator.class)
public #interface IpAddress{
String message() default "{ipAddress.invalid}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
What do I need to do to get this working?
You used the wrong #Target. You meant to use java.lang.annotation.Target but imported org.hibernate.annotations.Target. Change the first import to import java.lang.annotation.Target and it should work fine.
I'm trying to write a VERY simple test, using powermock and Robolectric. Here's my code:
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PowerMockIgnore;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.robolectric.RobolectricTestRunner;
import org.junit.Test;
import org.junit.runner.RunWith;
#RunWith(RobolectricTestRunner.class)
#PowerMockIgnore({ "org.mockito.*", "org.robolectric.*", "android.*" })
#PrepareForTest(BadStaticClass.class)
public class SomeActivityTest {
#Test
public void testSomething() {
PowerMockito.mockStatic(BadStaticClass.class);
Mockito.when(BadStaticClass.dontWantThisMethod()).thenReturn(false);
new SomeActivity().usesStatic();
}
}
Basically, i have a class, "SomeActivity", and it has a method that makes a call to BadStaticClass.dontWantThisMethod(). i want that static method to be stubbed out.
why is my code not working?
i kept getting errors like:
you are trying to stub a final method, you naughty developer!
which, i thought the whole point of PowerMock was to not see that.
According to the PowerMock API you have to include #RunWith(PowerMockRunner.class) for certain versions of JUnit, etc. However you also need to be using #RunWith(RobolectricTestRunner.class) and cannot specify more than one #RunWith on a Class.
So what to do?
I suspect you can keep your code above and introduce a JUnit #Rule (see: PowerMockRule docs) and also described in this similar post. Just be sure you check the versions of the Jars you are using so that they match those described in that other SO post. All too often things just won't work unless you get compatible versions, and it's not always obvious what versions are compatible.
The below error appears, when I import Runwith, in org.junit.runner...
The attribute value is undefined for the annotation type Runwith
It gave me the suggestion for creating a class in the Junit-Runner package...I don't know, what should I put in that code...
Junit-4.10 is there in libraries and Build Path. I am using it and am not sure whether it is an issue with Junit or Selenium...Any suggestions pls..??
This is the code, I am using and getting the error where the #Runwith is used.(Line #2 and #5)
package package1;
import org.junit.runner.Runwith;
import org.junit.runners.Suite.SuiteClasses;
#Runwith(Suite.Class)
#SuiteClasses({WPHomePage.class, WPRegisterpage.class})
public class BatchJavaFile {
}
#Runwith(Suite.Class) should be #RunWith(Suite.class) (note capitalization)
You probably also need another import
import org.junit.runners.Suite;