In IntelliJ, with a Springboot project (2.6.6) using JUnit 5, given the following test class, IntelliJ doesn't display exceptions occuring in the #BeforeAll method.
#ExtendWith(SpringExtension.class)
public class SpringTest {
private Object OBJECT = new Object();
#BeforeAll
public static void before() {
throw new RuntimeException("SpringTest.RuntimeException"); // replace by actual business code
}
#Test
public void test() {
// Doesn't matter
assertNotNull(this.OBJECT);
}
Running the class within IntelliJ (only this class)
Running the package of the test
When the #BeforeAll method is more complex, it's hard to understand that an exception occured, until you run the whole test package by chance.
In JUnit 4 with a #Before method, IntelliJ was showing test failure, with the stacktrace of the exception (which makes things easier to debug).
My pom.xml only dependencies are spring-boot-starter & spring-boot-starter-test.
Is this a bug / Is there any solution to reproduce the old behaviour ?
Stack:
Spring boot 2.6.6 / JUnit 5
IntelliJ IDEA 2022.1 Build #IU-221.5080.210
OpenJDK_x64Temurin_11.0.14.1_1 / Maven-3.8.4
Edit
As pointed out in the comment, to reproduce #Before of JUnit4, you should use #BeforeEach in Junit 5. In this case, IntelliJ will behave as before and display exceptions even when running only the given test class.
For the #BeforeAll, question is still pending.
Edit 2
A bug has been opened for the #BeforeAll exceptions: https://youtrack.jetbrains.com/issue/IDEA-292662
Bug resolved in IntelliJ 2022.1.1 Preview.
See YouTrack: IDEA-292662
I am testing my Quarkus application, and I would like to ignore some of my tests.
The test class is annotated with #io.quarkus.test.junit.QuarkusTest, and each method with #org.junit.jupiter.api.Test
I'm trying to use the #org.junit.Ignore annotation, but it's not working, the ignored tests are executed anyway.
This is the code:
#QuarkusTest
#TestHTTPEndpoint(MyResource::class)
class MyResourceTest {
#Test
#Ignore
fun `to be ignored`() {
assertTrue(false)
}
}
Does anyone know how can I achieve this?
You can use #Disabled annotation
You can also conditionally run tests with assumptions.
It seems to me that having annotations in different order breaks my build.
Does annotations order matter?
Answers from above say, in general, annotations order should not matter. In my case it is breaking.
This is module commons
#ConditionalOnProperty(value = "calculatorEnabled", havingValue = "true")
#Component
class Calculator {
// some logic
}
#ConditionalOnBean(Calculator.class)
#Service
class CalculationService {
private final Calculator calculator;
#Autowired
public CalculationService(final Calculator calculator) {
this.calculator = calculator;
}
// some logic
}
#RequestMapping(value = "/calculations", produces = MediaType.APPLICATION_JSON_VALUE)
#ConditionalOnBean(CalculationService.class)
#RestController
class CalculationController {
}
let there be another module - advanced-calculations
which has module commons as a dependency (maven dependency).
Please, note, there are two maven modules on purpose.
So CalculationController is available in other modules that use commons dependency.
Now, let me have two tests in advanced-calculations. (Again, I decided to test CalculationController) in another module.
I know that it is better to have tests in the module that actually defines a component, but commons module was written by other team long time ago; and for now we have to use it.
I want to make sure if we update version of commons, the app should not break (API should not change). Therefore, I added integration tests for CalculationContrioller into advanced-calculation module.
#SpringBootTest(classes = [AdvancedCalculationApplication.class],properties = ["calculatorEnabled=true" ])
#AutoConfigureMockMvc
AdvancedCalculationsITTest extends Specification {
}
and
#SpringBootTest(classes = [AdvancedCalculationApplication.class],properties = ["calculatorEnabled=" ])
#DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
#AutoConfigureMockMvc
AdvancedCalculationsITTestsDisabled extends Specification {
}
mvn clean install fails because AdvancedCalculationsITTest fails. Error cannot autowire CalculationController because there is no candidate calculationService.
However, when I change slightly order of annotations, it works
#ConditionalOnBean(CalculationService.class)
#RequestMapping(value = "/calculations", produces = MediaType.APPLICATION_JSON_VALUE)
#RestController
class CalculationController {
}
I will update this answer, but a bit later.
For me TODO.
(I will make a demo and add a link to github and put some code examples).
Your ideas and suggestions are welcome!
I have 2 custom annotations (RUNTIME) on a method: one annotation that makes a method always to throw an exception #Exceptional, another #Catchable that always catches an exception. Let this method return void for simplicity. By placing these annotations in different order, you should get a different result.
#Catchable
#Exceptional
public void processAction() {
// There is nothing that throws an exception.
safeStatement1();
safeStatement2();
safeStatementN();
}
vs
#Exceptional
#Catchable
public void processAction() {
// There is nothing that throws an exception.
safeStatement1();
safeStatement2();
safeStatementN();
}
By having these annotations in different order, the result should be different.
it is very simple to implement injection of objects into a testNG test class, it is handled mostly for us, however how can I build google guice DI into my framework and use it for classes which are not necessarily tests?
I want to inject using simple dependency injection for dependencies of my Page Object classes, these are nothing really to do with testNG, so how can we get the dependencies initialized for those?
Here is a simple example piece of code I want to replace:
public class HeaderComponent extends AbstractBasePageObject {
private static final Logger LOG = LoggerFactory.getLogger(HeaderComponent.class);
private MenuComponent menu = new MenuComponent(getDriver());
public HeaderComponent(NgWebDriver ngdriver) {
super(ngdriver);
}
public MenuComponent getMenuComponent() {
return menu;
}
}
This class is absolutely nothing to do with testNG itself, so how can I initialize everything for the outcome of:
#Inject
MenuComponent menu
Everything I try the menu throws a nullPointerException because I am having trouble having guice somewhat loaded I think.
I have create some general example for you - test with injection example
It works as you're expecting, I hope. It provides some test configs, injects them to driver and at last driver is injected in test component.
Result test looks like:
import com.google.inject.Inject;
import org.testng.annotations.Guice;
import org.testng.annotations.Test;
#Guice(modules = {TestModule.class})
public class SimpleTest {
#Inject
ComponentUnderTest component;
#Test
public void sampleTest() {
System.out.println(component.getParamToTest());
System.out.println(component.param);
System.out.println(component.elseone);
}
}
I have the following simple code. I have a class (TestClass) and I want to test "someMethod". There is an external static method which is called by my "someMethod".
I want to Powermock that static method to return me some dummy object.
I have the #PrepareForTest(ExternalClass.class) in the begining, but when I execute it gives the error:
The class ExternalClass 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.
Please help me to point out what is wrong with the way I have used #PrepareForTest
#RunWith(PowerMockRunner.class)
#PrepareForTest(ExternalClass.class)
public class xyzTest {
#Mock
private RestTemplate restTemplate;
#Mock
private TestClass testClass;
#BeforeClass
private void setUpBeforeClass() {
MockitoAnnotations.initMocks(this);
}
#Test
public void testSuccessCase() {
Boolean mockResponse = true;
ResponseEntity<Boolean> response = new ResponseEntity<Boolean>(mockResponse, HttpStatus.OK);
SomeClass someClass = new SomeClass("test", "1.0.0", "someUrl", "someMetaData");
PowerMockito.mockStatic(ExternalClass.class);
Mockito.when(restTemplate.postForEntity(any(String.class), any(String.class), eq(Boolean.class))).thenReturn(response);
Mockito.when(ExternalClass.getSomeClass(any(String.class))).thenReturn(someClass);
Boolean result = testClass.someMethod("test");
Assert.isTrue(result);
Mockito.verify(restTemplate, times(1)).postForObject(any(String.class), any(String.class), any());
}
}
Make sure you add #RunWith(PowerMockRunner.class) to the top of your class as well.
::edit:: two years later...
Don't ever use PowerMockito, you shouldn't need to.
If you do need to, you have most likely broken the SOLID principles and your design is wrong.
Fix your design instead.
As with the last answer, my problem was also mixing the Test annotation from TestNG instead of Junit Test.
import org.junit.Test; // works
import org.testng.annotations.Test // did not work
Very abstruse error and I spent more than 5 hrs debugging :(
For those trying to get this working with Junit 5, If your using the powermock-module-junit4 beta release which claims to be compatible with 4+, the library will still not recognize:
import org.junit.jupiter.api.Test;
and it will throw a:
org.powermock.api.mockito.ClassNotPreparedException
when #PrepareForTest is applied on the class you want to static mock. If you want to use PowerMock, you will have to go back to Junit 4 or create a MockWrapper for your static method at this time.
PowerMock 2.0: Github Roadmap
While the top-rated answer here is correct without a doubt, this does not answer the question of why is that needed; or, for example, why the same thing would not work with adding #RunWith(MockitoJUnitRunner.class).
The thing is PowerMockRunner uses instrumentation API under the hood, via
javassist library, this allows to alter the classes, like remove final or mock static (non-compile time constants).
In the process of modifying (instrumenting) a certain class, they add an interface to that, called PowerMockModified. It is a marker interface that denotes that a certain byte-code instrumentation took place. Later in the code, they simply check if the class that you use in #PrepareForTest was actually instrumented in some way or not, via such a method:
private boolean isModifiedByPowerMock() {
return PowerMockModified.class.isAssignableFrom(this.type);
}
In turns out that PowerMockRunner does some instrumentation, while MockitoJUnitRunner does not; thus the error you get.
I had the same error, resolved this by adding
#Rule
public PowerMockRule rule = new PowerMockRule();
inside the test class.
If above answers don't work try extends PowerMockTestCase. This trick worked for me.
Example:
public class xyzTest extends PowerMockTestCase
check if import org.junit.Test; package has imported and not that api jupiter one.
I had the same error but resolved it. My problem was that I included powermock-module-junit4 but included my test annotation from TestNG instead of Junit.
I had the same error. I was using TestNG to run the tests. I had to use the following method to fix the above issue.
#ObjectFactory
public IObjectFactory getObjectFactory() {
return new PowerMockObjectFactory();
}
For testNG there are 2 options as follows :
Using ObjectFactory as below:
#ObjectFactory
public IObjectFactory getObjectFactory() {
return new PowerMockObjectFactory();
}
Test class extending extends org.powermock.modules.testng.PowerMockTestCase
My gradle was using Junit 5.
test {
useJUnitPlatform()
}
I was able to debug this. By having breakpoints in PowerMockRunner methods.
It was not invoked. Moreover JUnit 5 is not supported with PowerMockito.
Looks like JUnit5 runs without #ExtendWith.
Make sure you are using powermock2. I had this problem when I was using powermock.
Use
import org.powermock2.api.mockito.PowerMockito;