Is there a way say,
import org.junit.Test;
public interface ITest {
#Test
public void runTest();
}
when I inherit this in a class it will automatically do this
public class Test implements ITest {
#Test
public void runTest() { }
}
instead of #Override?
By default annotations in Java are not inherited. If an annotation type has the meta-annotation #Inherited then it will be, but I don't think #Test does.
Related
I try to mock a static class PowerMockito.mockStatic(Static.class);. When #RunWith(PowerMockRunner.class), the code runs successfully but when I use #ExtendWith(MockitoExtension.class), it throws org.powermock.api.mockito.ClassNotPreparedException. Is it possible to mock a static class with #ExtendWith(MockitoExtension.class)?
This is my setup
#RunWith(PowerMockRunner.class)
#PrepareForTest({SmeRestClient.class})
public class PreScreeningServiceImplTest extends PreScreeningServiceImplTestHelper {
#Before
public void setup() {
PowerMockito.mockStatic(Static.class);
}
}
#RunWith(JUnitParamsRunner.class)
#ExtendWith(MockitoExtension.class)
#PrepareForTest(SmeRestClient.class)
public class PreScreeningServiceImplTest extends PreScreeningServiceImplTestHelper {
#Before
public void setup() {
PowerMockito.mockStatic(Static.class);
}
}
Full error code
org.powermock.api.mockito.ClassNotPreparedException:
The class com.ime.restful.Static not prepared for test.
To prepare this class, add class to the '#PrepareForTest' annotation.
In case if you don't use this annotation, add the annotation on class or method level.
I have a custom annotation which I use as config to start off one time set-up for Junit.
#Target(TYPE) #Retention(RUNTIME)
public #interface MyAnnotation{
String host();
int port();
}
Test class:
#MyAnnotation(host="0.0.0.0", port=4567)
public class MyTest extends MyAbstractClass{
#Test
public void myTest(){
//do testy things
}
}
Superclass:
public class MyAbstractClass{
#BeforeAll
public static void start(){
Config cfg = readConfig();
//Use config to do one time set-up
}
private static Config readConfig(){
MyAnnotation ann = MyTest.class.getAnnotation(MyAnnotation.class);
return new Config(ann.host(), ann.port());
}
}
So currently, I hardcode the name of the test class (MyTest) in readConfig(..).
This won't work when I add a second test class.
One way to solve it is:
Add another #BeforeAll method in MyTest which will call the #BeforeAll in super-class and pass the class name as a param.
However, I am curious if I can read the name of the executing subclass in the superclass via some reflexion magic.
Any ideas are most welcome.
Thanks
The presence of the #BeforeAll annotation suggests you are using JUnit 5. In this case, you can use.
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.TestInfo;
public class MyAbstractClass {
#BeforeAll
public static void start(TestInfo ti) {
Config cfg=readConfig(ti.getTestClass().orElseThrow(IllegalStateException::new));
//Use config to do one time set-up
}
private static Config readConfig(Class<?> testClass) {
MyAnnotation ann = testClass.getAnnotation(MyAnnotation.class);
return new Config(ann.host(), ann.port());
}
}
See also the TestInfo API documentation.
This is not “Reflection Magic” but a feature provided by JUnit itself, but it’s also only JUnit which knows that the invocation of a static method annotated with #BeforeAll is associated with a particular test class it is going to process.
I have a little problem here, and I don't know how to solve it.
I have a class which have to make tests for some JSF beans.
In order to achieve that, I used PowerMock with Mockito for mocking the FacesContext, RequestContext and another static methods which are used inside the JSF beans.
#PrepareForTest(ClassWithStaticMethods.class)
#RunWith(PowerMockRunner.class)
#FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class MyTestingClass extends SomeTestBaseClass{
#BeforeClass
public static void init() throws Exception{
//mocking the FacesContext and others
}
#Test
public void test0001Create(){}
#Test
public void test0002Edit(){}
#Test
public void test0003Delete(){}
}
The SomeTestBaseClass, nothing complicated.
public abstract class SomeTestBaseClass {
#BeforeClass
public static void setUpBeforeClass() throws Exception {
//...
}
#AfterClass
public static void tearDownAfterClass() throws Exception {
//...
}
}
The problem is that the order of tests is ignored (even with the FixMethodOrder annotation). If I remove PowerMockRunner (and the RunWith annotation), the order is kept but the mocking for static (and void) methods doesn't work.
But leaving the class with PowerMockRunner, the annotation #FixMethodOrder is ignored, totally.
I even tried with MockitoJUnitRunner, and here the order of tests is kept, but the mocking for static (and void) methods isn't done.
Does anyone have any idea why it is happening?
Thanks
I had the same problem getting them to run in the right order.
I solved it by using the #PowerMockRunnerDelegate annotation.
In my test class annotations:
#FixMethodOrder(MethodSorters.NAME_ASCENDING)
#RunWith(PowerMockRunner.class)
I added #PowerMockRunnerDelegate(JUnit4.class):
#FixMethodOrder(MethodSorters.NAME_ASCENDING)
#RunWith(PowerMockRunner.class)
#PowerMockRunnerDelegate(JUnit4.class)
They now run in the expected order.
I believe this works because then it's not PowerMock that's running the tests, but JUnit 4 itself.
Like a workaround: Create a new method (let's say 'testAll'), put #Test annotation just for this (remove the #Test annotation from the rest of the methods), and then, call your testing methods inside of the annoted method.
Dirty, but it works.
#PrepareForTest(ClassWithStaticMethods.class)
#RunWith(PowerMockRunner.class)
#FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class MyTestingClass extends SomeTestBaseClass{
#BeforeClass
public static void init() throws Exception{
//mocking the FacesContext and others
}
#Test
public void testAll(){
this.test0001Create();
this.test0002Edit();
this.test0003Delete();
}
public void test0001Create(){}
public void test0002Edit(){}
public void test0003Delete(){}
}
Please try to change sequence:
#FixMethodOrder(MethodSorters.NAME_ASCENDING)
#RunWith(PowerMockRunner.class)
#PrepareForTest(ClassWithStaticMethods.class)
I don't know why it doesn't work with the PowerMockRunner annotation but instead you could use a PowerMockRule
#FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class MyTestingClass extends SomeTestBaseClass {
#Rule
public PowerMockRule rule = new PowerMockRule();
#BeforeClass
public static void init() throws Exception {
// mocking the FacesContext and others
}
#Test
public void test0001Create() {
}
#Test
public void test0002Create() {
}
#Test
public void test0003Create() {
}
}
In JUnit, you can create test suites like so:
public class SecurityTest1 {
#Test
public void testSecurity1() {
// ...
}
}
public class LoadTest1 {
#Test
public void testLoad1() {
// ...
}
}
public class SecurityTest2 {
#Test
public void testSecurity2() {
// ...
}
}
#RunWith(Suite.class)
#SuiteClasses({SecurityTest1.class, SecurityTest2.class})
public class SecurityTestSuite {}
But this seems rather cumbersome. It would be so nice to define a simple class-level annotation:
#Retention(RetentionPolicy.RUNTIME)
#Target(ElementType.TYPE)
public #interface SecurityTest {}
And then define your suite like so:
#SecurityTest
public class SecurityTest1 {
#Test
public void testSecurity1() {
// ...
}
}
public class LoadTest1 {
#Test
public void testLoad1() {
// ...
}
}
#SecurityTest
public class SecurityTest2 {
#Test
public void testSecurity2() {
// ...
}
}
#RunWith(Suite.class)
#SuiteClasses({SecurityTest.class})
public class SecurityTestSuite {}
Is this possible? If so how? Note: not interested in switching to TestNG or any other test framework if JUnit does not support this...thanks in advance!
You can do it by implementing your own Test Runner similar to the Suite runner.
This runner should extract the marker annotation class from the value of the #SuiteClasses annotation (you should probably replace #SuiteClasses with your own annotation). Take a look at the getAnnotatedClasses method of the org.junit.runners.Suite class.
After having the marker annotation class, you should scan the classpath for test classes marked with this annotation (use a library such as Reflections) and pass an array of them to the appropriate Runner constructor.
You can find a similar behavior in the Suite constructor:
public Suite(Class<?> klass, RunnerBuilder builder) throws InitializationError {
this(builder, klass, getAnnotatedClasses(klass));
}
I read about Structuring Unit Tests with having a test class per class and an inner class per method. Figured that seemed like a handy way to organize the tests, so I tried it in our Java project. However, the tests in the inner classes doesn't seem to be picked up at all.
I did it roughly like this:
public class DogTests
{
public class BarkTests
{
#Test
public void quietBark_IsAtLeastAudible() { }
#Test
public void loudBark_ScaresAveragePerson() { }
}
public class EatTests
{
#Test
public void normalFood_IsEaten() { }
#Test
public void badFood_ThrowsFit() { }
}
}
Does JUnit not support this, or am I just doing it wrong?
You should annontate your class with #RunWith(Enclosed.class), and like others said, declare the inner classes as static:
#RunWith(Enclosed.class)
public class DogTests
{
public static class BarkTests
{
#Test
public void quietBark_IsAtLeastAudible() { }
#Test
public void loudBark_ScaresAveragePerson() { }
}
public static class EatTests
{
#Test
public void normalFood_IsEaten() { }
#Test
public void badFood_ThrowsFit() { }
}
}
public class ServicesTest extends TestBase {
public static class TestLogon{
#Test
public void testLogonRequest() throws Exception {
//My Test Code
}
}
}
Making the inner class static works for me.
In JUnit 5, you simply mark non-static inner classes as #Nested:
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
public class DogTests {
#Nested
public class BarkTests {
#Test
public void quietBark_IsAtLeastAudible() { }
#Test
public void loudBark_ScaresAveragePerson() { }
}
#Nested
public class EatTests {
#Test
public void normalFood_IsEaten() { }
#Test
public void badFood_ThrowsFit() { }
}
}
I think some of the answers might be for older versions of JUnit. In JUnit 4 this worked for me:
#RunWith(Suite.class)
#Suite.SuiteClasses({ DogTests.BarkTests.class, DogTests.EatTests.class })
public class DogTests
{
public static class BarkTests
{
#Test
public void quietBark_IsAtLeastAudible() { }
#Test
public void loudBark_ScaresAveragePerson() { }
}
public static class EatTests
{
#Test
public void normalFood_IsEaten() { }
#Test
public void badFood_ThrowsFit() { }
}
}
I've had success with Nitor Creation's Nested Runner as well.
How to use Nitor Creation's Nested Runner
There is a post explaining it here:
Add this dependency:
<dependency>
<groupId>com.nitorcreations</groupId>
<artifactId>junit-runners</artifactId>
<version>1.2</version>
<scope>test</scope>
</dependency>
And a #RunWith to your test:
import com.nitorcreations.junit.runners.NestedRunner
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.*;
#RunWith(NestedRunner.class)
public class RepositoryUserServiceTest {
public class RegisterNewUserAccount {
public class WhenUserUsesSocialSignIn {
public class WhenUserAccountIsFoundWithEmailAddress {
#Test
public void shouldThrowException() {
assertTrue(true);
}
}
}
}
}
PS: The example code has been taken and modified from the above blog post
I just ran across this posting (11 years later) regarding the testing of inner classes. An inner class can be trivially converted to equivalent static form only if the class should have been static in the first place. Static inner classes are not really inner classes because there is no enclosing this. They have exactly the same semantics (except for visibility restrictions) as top-level classes.
To test a "true" inner class [one that depends on its enclosing instance] you need to use the interface that the Java language provides for creating inner class instances outside the scope of the enclosing class. That interface includes an extra parameter in each constructor which is the enclosing instance. In this way, the Java compiler converts an inner class to a special top-level class with a mangled name (lots of $ signs) and augmented constructors. The same transformation can be performed at the source level. In principle, these transformed classes can be tested but it is a complex process because the tested program has transformed syntax and the test code must construct a (mock) object that serves as the enclosing instance.
Another way to test true inner classes is to write an executable method contract for each method consisting of an executable logical pre-condition and an executable logical post-condition. Then these executable contracts can be evaluated in the course of running a conventional top-level test that invokes the inner class methods.
In practice, I typically settle for the indirect testing of inner class methods in the course of top-level testing. Writing and testing executable contracts for all methods is a more rigorous, albeit significantly more expensive, alternative.