When to use #BeforeClass in JunitTests? - java

#BeforeClass doesn't really make sense to me. Everything in that method will be executed before all test cases. But couldn't we write that simply at the beginning of the test class and have the same effect?

You can "technically" do the same, however you have differents behaviors behind the scenes, since #BeforeClass is handled by JUnit whilst standard java code in statics blocks or class initializers are handled by the JVM.
You can "compare" #BeforeClass with jvm static blocks but #BeforeClass is called by JUnit while statics blocks are called by the JVM.
In case you have a failure in your initializers (either JUnit or JVM), you will have a different errors.
Handled by JUnit
public class TestCase {
static private int number;
#BeforeClass
public static void init(){
number = 1/0; // Makes a failure
}
}
// THROWS THIS STACK TRACE
java.lang.ArithmeticException: / by zero
at com.creditsesame.integration.util.GenericUtilsTest.test(GenericUtilsTest.java:26)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
Maven Test goal output
Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.005 sec <<< FAILURE! - in com.fede.TestCase
com.fede.TestCase Time elapsed: 0.005 sec <<< ERROR!
java.lang.ArithmeticException: / by zero
at com.fede.TestCase.init(TestCase.java:24)
Results :
Tests in error:
TestCase.init:24 Arithmetic / by zero
Tests run: 1, Failures: 0, Errors: 1, Skipped: 0
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 13.864 s
[INFO] Finished at: 2015-10-02T11:35:32-06:00
[INFO] Final Memory: 33M/448M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.18.1:test (default-test) on project integration: There are test failures.
[ERROR]
[ERROR] Please refer to E:\Project\workspace\fede\target\surefire-reports for the individual test results.
[ERROR] -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoFailureException
Handled by JVM
public class TestCase {
static int i=1/0; // Makes a failure
#BeforeClass
public static void init(){
number = 1/0;
}
}
// THROWS THIS STACK TRACE
java.lang.ExceptionInInitializerError
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
Caused by: java.lang.ArithmeticException: / by zero
Maven Test goal output
Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.008 sec - in com.fede.TestCase
Results :
Tests run: 1, Failures: 0, Errors: 1, Skipped: 0
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 01:09 min
[INFO] Finished at: 2015-10-02T11:34:02-06:00
[INFO] Final Memory: 28M/607M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.18.1:test (default-test) on project integration: ExecutionException: java.lang.RuntimeException: There was an error in the forked process
[ERROR] java.lang.ExceptionInInitializerError
[ERROR] at java.lang.Class.forName0(Native Method)
[ERROR] at java.lang.Class.forName(Class.java:191)
[ERROR] at org.junit.runner.Description.getTestClass(Description.java:206)
[ERROR] at org.apache.maven.surefire.common.junit48.FilterFactory$GroupMatcherCategoryFilter.shouldRun(FilterFactory.java:281)
[ERROR] at org.apache.maven.surefire.common.junit48.FilterFactory$GroupMatcherCategoryFilter.shouldRun(FilterFactory.java:227)
[ERROR] at org.junit.runners.ParentRunner.shouldRun(ParentRunner.java:299)
[ERROR] at org.junit.runners.ParentRunner.filter(ParentRunner.java:254)
[ERROR] at org.junit.runner.manipulation.Filter.apply(Filter.java:79)
[ERROR] at org.apache.maven.surefire.junitcore.JUnitCoreWrapper$FilteringRequest.<init>(JUnitCoreWrapper.java:139)
[ERROR] at org.apache.maven.surefire.junitcore.JUnitCoreWrapper.createRequestAndRun(JUnitCoreWrapper.java:100)
[ERROR] at org.apache.maven.surefire.junitcore.JUnitCoreWrapper.executeEager(JUnitCoreWrapper.java:78)
[ERROR] at org.apache.maven.surefire.junitcore.JUnitCoreWrapper.execute(JUnitCoreWrapper.java:54)
[ERROR] at org.apache.maven.surefire.junitcore.JUnitCoreProvider.invoke(JUnitCoreProvider.java:144)
[ERROR] at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:203)
[ERROR] at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:155)
[ERROR] at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:103)
[ERROR] Caused by: java.lang.ArithmeticException: / by zero
[ERROR] at com.creditsesame.integration.util.GenericUtilsTest.<clinit>(GenericUtilsTest.java:22)
[ERROR] ... 16 more
[ERROR] -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoFailureException
JUnit comments
When you annotate with #BeforeClass the method is executed only once, this is useful for initializations/loggings you want to happen just once. You can check a very useful link explaining this here. The difference with #Before is that it is being executed after each test case.
Take a look at this example:
package com.javacodegeeks.junit;
import static org.junit.Assert.*;
import java.util.ArrayList;
import org.junit.*;
public class JunitTestExample {
private ArrayList testList;
#BeforeClass
public static void onceExecutedBeforeAll() {
System.out.println("#BeforeClass: onceExecutedBeforeAll");
}
#Before
public void executedBeforeEach() {
testList = new ArrayList();
System.out.println("#Before: executedBeforeEach");
}
#Test
public void EmptyCollection() {
assertTrue(testList.isEmpty());
System.out.println("#Test: EmptyArrayList");
}
#Test
public void OneItemCollection() {
testList.add("oneItem");
assertEquals(1, testList.size());
System.out.println("#Test: OneItemArrayList");
}
}
The output will be:
#BeforeClass: onceExecutedBeforeAll
#Before: executedBeforeEach
#Test: EmptyArrayList
#Before: executedBeforeEach
#Test: OneItemArrayList
You can find a detailed explanation in #BeforeClass vs static{}

I'm not sure what you mean by 'in the beginning of the class',
but the #BeforeClass method can be used to initialize a group of test case.
Imagine there is some kind of initialization that is time consuming and it is the same for a lot of test cases. You do not want to repeat that many times because that will make the whole testing running too long.

Related

Error cannot find symbol after try-catch block [duplicate]

This question already has answers here:
Why does a Try/Catch block create new variable scope?
(5 answers)
Closed 6 years ago.
I wasn't able to get apache commons cli to work.
apache commons-cli
I have the most simple start:
This is the only class.
Resources are added with maven(commandline).
import org.apache.commons.cli.*;
public class App {
public static void main(String[] args) {
// create Options object
Options options = new Options();
CommandLineParser parser = new DefaultParser();
// add t option
options.addOption("t", false, "display current time");
try{
CommandLine cmd = parser.parse( options, args);
}catch(ParseExeption ex){
}
if(cmd.hasOption("t")) {
// print the date and time
}else {
// print the date
}
}
}
No matter what I tried. I get the "cannot find symbol".
This is the last part of the error:
[ERROR] COMPILATION ERROR :
[INFO] -------------------------------------------------------------
[ERROR] /Users/peter/Code/java/using_archetypes/using_cli_1/src/main
/java/com/mkyong/core/utils/App.java:[27,8] cannot find symbol
symbol: class ParseExeption
location: class com.mkyong.core.utils.App
[ERROR] /Users/peter/Code/java/using_archetypes/using_cli_1/src/main
/java/com/mkyong/core/utils/App.java:[31,4] cannot find symbol
symbol: variable cmd
location: class com.mkyong.core.utils.App
[INFO] 2 errors
[INFO] -------------------------------------------------------------
[INFO]
-------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO]
-------------------------------------------------------------------
[INFO] Total time: 0.842 s
[INFO] Finished at: 2016-10-31T12:17:29+01:00
[INFO] Final Memory: 15M/309M
[INFO]
---------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-
compiler-plugin:3.1:compile (default-compile) on project
dateUtils2: Compilation failure: Compilation failure:
[ERROR] /Users/peter/Code/java/using_archetypes/using_cli_1/src/main
/java/com/mkyong/core/utils/App.java:[27,8] cannot find symbol
[ERROR] symbol: class ParseExeption
[ERROR] location: class com.mkyong.core.utils.App
[ERROR] /Users/peter/Code/java/using_archetypes/using_cli_1/src/main
/java/com/mkyong/core/utils/App.java:[31,4] cannot find symbol
[ERROR] symbol: variable cmd
[ERROR] location: class com.mkyong.core.utils.App
[ERROR] -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven
with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug
logging.
[ERROR]
[ERROR] For more information about the errors and possible
solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN
/MojoFailureException
Please help me to start with the commons-cli.
This is compiled with the maven compiler.
thank you.
Simply replace ParseExeption with ParseExceptionand move the if/else block in the same code block as where you defined your variable cmd otherwise it won't be visible, for example as next:
public static void main(String[] args) throws ParseException{
// create Options object
Options options = new Options();
CommandLineParser parser = new DefaultParser();
// add t option
options.addOption("t", false, "display current time");
CommandLine cmd = parser.parse( options, args);
if(cmd.hasOption("t")) {
// print the date and time
}else {
// print the date
}
}

errors when trying extract package name from Class variable

In my current project, i have this code:
for(Annotation annotation : field.getAnnotations()) {
String package = annotation.annotationType().getPackage().getName();
if(package.equals("com.loja.annotations.input_type"))
input.setAttribute("type", annotation.annotationType().getSimpleName());
}
when i try build the project, this code causes a compilation failure due to this error:
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.1:compile (default-compile) on project store: Compilation failure: Compilation failure:
[ERROR] /c:/Users/Kleber Mota/Documents/GitHub/app/src/main/java/com/loja/thymeleaf/processor/form/InputProcessor.java:[37,11] not a statement
[ERROR] /c:/Users/Kleber Mota/Documents/GitHub/app/src/main/java/com/loja/thymeleaf/processor/form/InputProcessor.java:[37,17] ';' expected
[ERROR] /c:/Users/Kleber Mota/Documents/GitHub/app/src/main/java/com/loja/thymeleaf/processor/form/InputProcessor.java:[38,14] illegal start of expression
[ERROR] /c:/Users/Kleber Mota/Documents/GitHub/app/src/main/java/com/loja/thymeleaf/processor/form/InputProcessor.java:[38,21] illegal start of expression
[ERROR] /c:/Users/Kleber Mota/Documents/GitHub/app/src/main/java/com/loja/thymeleaf/processor/form/InputProcessor.java:[38,28] ';' expected
[ERROR] /c:/Users/Kleber Mota/Documents/GitHub/app/src/main/java/com/loja/thymeleaf/processor/form/InputProcessor.java:[38,22] variable declaration not allowed here
anyone can see what's wrong here?
line 37 is: String package = annotation.annotationType().getPackage().getName(); and line 38 is if(package.equals("com.loja.annotations.input_type"))
you can try this..
annotation.annotationType().getName();
You can print out your "package" variable after line 37 (before if).
I wrote and ran the similar code and it worked for me. I created a custom annotation in my api package and line 37 returned "api".

Execute JPA query on GlobalSetting.onStart() in PLayframework

How can I do some db operation on playframework global class method on start.
I would like to put some data to db from other source.
For now I have:
My code:
public class Global extends GlobalSettings {
#Override
#Transactional
public void onStart(Application application) {
Akka.system().scheduler().schedule(
Duration.create(1, TimeUnit.SECONDS), // start task delay
Duration.create(24, TimeUnit.HOURS), // between task instance delay
//Duration.create(24, TimeUnit.HOURS), // between task instance delay
new Runnable() {
#Override
#Transactional
public void run() {
System.out.println("Importing CRM data...");
ImportCrmData.start();
System.out.println("... imported");
}
},
Akka.system().dispatcher()
);
I am getting an error:
[info] play - Shutdown application default Akka system.
[info] play - datasource [jdbc:mysql://localhost/svp] bound to JNDI as DefaultDS
[info] play - datasource [jdbc:mysql://192.168.0.4/scrm_customer] bound to JNDI as CRM
[info] play - database [default] connected at jdbc:mysql://localhost/svp
[info] play - database [crm] connected at jdbc:mysql://192.168.0.4/scrm_customer
[info] play - Starting application default Akka system.
[info] play - Application started (Dev)
Importing CRM data...
[ERROR] [12/08/2014 15:57:04.773] [application-akka.actor.default-dispatcher-3] [TaskInvocation] No EntityManager bound to this thread. Try wrapping this call in JPA.withTransaction, or ensure that the HTTP context is setup on this thread.
java.lang.RuntimeException: No EntityManager bound to this thread. Try wrapping this call in JPA.withTransaction, or ensure that the HTTP context is setup on this thread.
at play.db.jpa.JPA.em(JPA.java:55)
at models.Customer.getByCrmId(Customer.java:185)
at models.CustomerCRM.importCrmData(CustomerCRM.java:84)
at actions.ImportCrmData.start(ImportCrmData.java:28)
at Global$1.run(Global.java:40)
at akka.actor.LightArrayRevolverScheduler$$anon$3$$anon$2.run(Scheduler.scala:241)
at akka.dispatch.TaskInvocation.run(AbstractDispatcher.scala:42)
at akka.dispatch.ForkJoinExecutorConfigurator$AkkaForkJoinTask.exec(AbstractDispatcher.scala:386)
at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)
Please give me some help.
I use playframework 2.2.4 with java
-------------------------------------EDIT-----------------------------------------
Afted adding:
JPA.withTransaction(() -> {
ImportCrmData.start();
});
I am getting error.
[info] Compiling 1 Java source to app/modules/common/target/scala-2.10/classes...
[error] app/modules/common/app/Global.java:38: error: illegal start of expression
[error] JPA.withTransaction(() -> {
[error] ^
[error] app/modules/common/app/Global.java:38: error: illegal start of expression
[error] JPA.withTransaction(() -> {
[error] ^
[error] app/modules/common/app/Global.java:38: error: illegal start of expression
[error] JPA.withTransaction(() -> {
[error] ^
[error] app/modules/common/app/Global.java:38: error: ';' expected
[error] JPA.withTransaction(() -> {
[error] ^
[error] app/modules/common/app/Global.java:39: error: illegal start of expression
[error] ImportCrmData.start();
[error] ^
[error] app/modules/common/app/Global.java:39: error: ';' expected
[error] ImportCrmData.start();
[error] ^
[error] app/modules/common/app/Global.java:40: error: illegal start of type
[error] });
[error] ^
[error] app/modules/common/app/Global.java:41: error: ')' expected
[error] }
[error] ^
[error] app/modules/common/app/Global.java:42: error: illegal start of expression
[error] },
[error] ^
[error] app/modules/common/app/Global.java:43: error: ';' expected
[error] Akka.system().dispatcher()
[error] ^
[error] app/modules/common/app/Global.java:43: error: ';' expected
[error] Akka.system().dispatcher()
[error] ^
[error] 11 errors
[error] (common/compile:compile) javac returned nonzero exit code
Finally I've added:
public void run() {
JPA.withTransaction(
ImportCrmData.start()
);
}
Remove #Transactional annotations, they are useful only in controllers. Wrap CRM import with JPA.withTransaction method. Java 8 syntax:
JPA.withTransaction(() -> {
ImportCrmData.start();
});
And non Java 8 syntax:
JPA.withTransaction(new Callback0() {
#Override
public void invoke() throws Throwable {
ImportCrmData.start();
}
});

Ebeans validation strange behaviour with custom message

I`ve got simple validation like:
#Column(length=6)
#Pattern(regexp = "[0-9]{2}( |-)?[0-9]{3}", message = Errors.kod_pocztowy)
private String kod_pocztowy;
But it return strange errors:
failed: java.lang.NoClassDefFoundError: javax/el/ELContext
[error] at org.hibernate.validator.messageinterpolation.ResourceBundleMessageInterpolator.interpolateExpression(ResourceBundleMessageInterpolator.java:227)
[error] at org.hibernate.validator.messageinterpolation.ResourceBundleMessageInterpolator.interpolateMessage(ResourceBundleMessageInterpolator.java:187)
[error] at org.hibernate.validator.messageinterpolation.ResourceBundleMessageInterpolator.interpolate(ResourceBundleMessageInterpolator.java:115)
[error] at org.hibernate.validator.internal.engine.ValidationContext.interpolate(ValidationContext.java:370)
[error] at org.hibernate.validator.internal.engine.ValidationContext.createConstraintViolation(ValidationContext.java:284)
[error] at org.hibernate.validator.internal.engine.ValidationContext.createConstraintViolations(ValidationContext.java:246)
[error] at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.validateSingleConstraint(ConstraintTree.java:289)
[error] at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.validateConstraints(ConstraintTree.java:133)
[error] at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.validateConstraints(ConstraintTree.java:91)
[error] at org.hibernate.validator.internal.metadata.core.MetaConstraint.validateConstraint(MetaConstraint.java:85)
[error] at org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraint(ValidatorImpl.java:478)
[error] at org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraintsForDefaultGroup(ValidatorImpl.java:424)
[error] at org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraintsForCurrentGroup(ValidatorImpl.java:388)
[error] at org.hibernate.validator.internal.engine.ValidatorImpl.validateInContext(ValidatorImpl.java:340)
[error] at org.hibernate.validator.internal.engine.ValidatorImpl.validate(ValidatorImpl.java:158)
When i`m changing message property to text like:
#Column(length=6)
#Pattern(regexp = "[0-9]{2}( |-)?[0-9]{3}", message = "Now its ok")
private String kod_pocztowy;
Then everything seems to be ok. What`s the problem ? Anyone can explain it for me?
Ok, i`ve found it by myself. Using chars like {} causes Ebean to load message from class and this message is related to that class.

NullPointerException on FakeApplication start

I'm writing unit tests for a web app and using the Java Play! (2.1.3) framework's FakeApplication class.
public class TagTest {
public static FakeApplication app;
...
// BeforeClass only runs once before any tests are run
#BeforeClass
public static void setUpBeforeClass() {
// Set up new FakeApplication before running any tests
app = Helpers.fakeApplication(Helpers.inMemoryDatabase());
Helpers.start(app);
}
...
}
I have the same setUpBeforeClass() method in all four of my test classes that test each of my four different models but when I run the play test command, all four test classes return a similar error:
[error] Test models.TagTest failed: java.lang.NullPointerException: null
[error] at Global.onStart(Global.java:59)
[error] at play.core.j.JavaGlobalSettingsAdapter.onStart(JavaGlobalSettingsAdapter.scala:17)
[error] at play.api.GlobalPlugin.onStart(GlobalSettings.scala:175)
[error] at play.api.Play$$anonfun$start$1$$anonfun$apply$mcV$sp$1.apply(Play.scala:68)
[error] at play.api.Play$$anonfun$start$1$$anonfun$apply$mcV$sp$1.apply(Play.scala:68)
[error] at scala.collection.immutable.List.foreach(List.scala:309)
[error] at play.api.Play$$anonfun$start$1.apply$mcV$sp(Play.scala:68)
[error] at play.api.Play$$anonfun$start$1.apply(Play.scala:68)
[error] at play.api.Play$$anonfun$start$1.apply(Play.scala:68)
[error] at play.utils.Threads$.withContextClassLoader(Threads.scala:18)
[error] at play.api.Play$.start(Play.scala:67)
[error] at play.api.Play.start(Play.scala)
[error] at play.test.Helpers.start(Helpers.java:354)
[error] at models.TagTest.setUpBeforeClass(TagTest.java:35)
Where line 35 is the line:
Helpers.start(app);
Is there something I'm doing wrong here?
Looks from the stack like the NPE is thrown on line 59 of your own Global class - inside your override of GlobalSettings.onStart()?
Look/debug there to see what the issue is. Hard to suggest any more without seeing your code - maybe check this out for a basic intro to Global and how it can be used.
By the way - just a couple of additional points
Why is app a static variable? It should probably be an instance variable of TagTest.
You didn't have to point out what code was on line 35 of TagTest - this can be seen on the second-last line of the stacktrace. The first line of the trace shows you the method in which the Exception was actually thrown - the rest just show the stack of calls which led up to that method call.

Categories