java: best practice to accessing objects in another test - java

I have two separate junit test .java files. it has the following convention below
import org.mockito.Mock;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
#Test (groups = "integration")
public class myOneIntegrationTest {
#BeforeMethod
#SneakyThrows
public void beforeMethod() {...}
#AfterMethod
public void afterMethod() {...}
#Test
#SneakyThrows
public void testOne() {...}
the test file is localized so that it is testing for one object
I need a test for a functionality that requires an object created in beforeMethod in javaOne.java and another object created in beforeMethod of javaTwo.java
i really dont want to copy-paste beforeMethod from each java files. Is it possible to just import it and test it in javaThree.java?

There is a creational pattern which is derived from the factory pattern called Object Mother.
Martin Fowler wrote an Article in 2006 about it with further readings.
In my opinion this is well suited for testing but you really should replace any boiler plate code with one generated through Lombok (e.g. #Builder).

Related

Junit 5 and Mockito 3: UnnecessaryStubbingException not thrown when injecting #Mock's through constructor

Looking at the two test classes below I assume the same behavior from them: to have an UnnecessaryStubbingException thrown. However MyTest2 does not. The MockitoExtension class should have strictness set to strict stubs by default. I can't seem to find any documented information about this behavior and I really want to understand it.
I prefer to write my tests as MyTest2 because I like to have final fields wherever possible, though I also really enjoy the strict stubs check done by Mockito.. Please help my understand the difference between the two tests.
package example;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;
#ExtendWith(MockitoExtension.class)
class MyTest {
#Mock
List<Integer> integerList;
#Test
void test() {
Mockito.when(integerList.size()).thenReturn(10);
System.out.println("Do something not involving list");
Assertions.assertTrue(true);
}
}
#ExtendWith(MockitoExtension.class)
class MyTest2 {
final List<Integer> integerList;
MyTest2(#Mock List<Integer> integerList) {
this.integerList = integerList;
}
#Test
void test() {
Mockito.when(integerList.size()).thenReturn(10);
System.out.println("Do something not involving list");
Assertions.assertTrue(true);
}
}
I found the reason in the mockito documentation:
Mockito JUnit Runner triggers UnnecessaryStubbingException only when none of the test methods use the stubbings. This means that it is ok to put default stubbing in a 'setup' method or in test class constructor. That default stubbing needs to be used at least once by one of the test methods.
If you do not want the exception to be thrown for the MyTest class, you can use Mockito.lenient or MockitoSettings. But I guess it is not possible to activate the exception for the MyTest2 class.

Cucumber 4: Implement Global Hooks

I'm new to Cucumber BDD testing v4.1.
Questions:
How to impelement before(setup) method in Cucumber 4 (DAO, Spring)?
Please help. Thanks.
Cucumber Hooks – Where to use #Before
#Before, in its most basic usage, allows you to run a block of code before every scenario. Normally in Cucumber, we tend to do the initialization related things – such as object initialization, data setup etc in the Given statement. Because of this a lot of people don’t see the need of using Cucumber’s #Before. But you can use #Before to make in an entry in your reporting that a new scenario is being executed. Since #Before always runs before every scenario, you can use this in your reports to clearly depict when a scenario starts executing.
It’s not necessary that you add #Before in each feature file. Just add it in any one feature file and let Cucumber do its job. Cucumber will figure out where you have saved #Before and then it will use it before all the scenarios. To make your reporting bit more useful and easy to understand, you can actually write the scenario name as well in the report. The Java code for this is given below –
#Before
public void before(Scenario scenario) {
System.out.println("------------------------------");
System.out.println("Starting - " + scenario.getName());
System.out.println("------------------------------");
}
Cucumber API provides an Interface called Scenario, using which you can get can instance of this class. In the above code, we have just used the getName() method of this interface to print the scenario name in our log.
Test Hooks with Single Scenario (Example):
Feature File
Feature: Test Hooks
Scenario: This scenario is to test hooks functionality
Given this is the first step
When this is the second step
Then this is the third step
Step Definitions:
package stepDefinition;
import cucumber.api.java.en.Given;
import cucumber.api.java.en.Then;
import cucumber.api.java.en.When;
public class Hooks_Steps {
#Given("^this is the first step$")
public void This_Is_The_First_Step(){
System.out.println("This is the first step");
}
#When("^this is the second step$")
public void This_Is_The_Second_Step(){
System.out.println("This is the second step");
}
#Then("^this is the third step$")
public void This_Is_The_Third_Step(){
System.out.println("This is the third step");
}
}
Hooks
package utilities;
import cucumber.api.java.After;
import cucumber.api.java.Before;
public class Hooks {
#Before
public void beforeScenario(){
System.out.println("This will run before the Scenario");
}
#After
public void afterScenario(){
System.out.println("This will run after the Scenario");
}
}
EDIT:
Workaround mentioned in Issue #515 and elsewhere is to use JUnit‘s #BeforeClass and #AfterClass annotations in the runner class, like this:
#RunWith(Cucumber.class)
#Cucumber.Options(format = {
"html:target/cucumber-html-report",
"json-pretty:target/cucumber-json-report.json"})
public class HooksTest {
#BeforeClass
public static void setup() {
System.out.println("Ran the before");
}
#AfterClass
public static void teardown() {
System.out.println("Ran the after");
}
}
Note: While #BeforeClass and #AfterClass may look like the cleanest solution at first, they are not very practical to use. They work only when Cucumber-JVM is set to use the JUnit runner. Other runners, like TestNG, the command line runner, and special IDE runners, won’t pick up these hooks. Their methods must also be are static and would need static variables or singletons to share data anyway.
to run JUnit test cases from the command line
I got the answers already which is implement ConcurrentEventListener.

CdiUnit test with Junit #Rule is impossible because of a public private field paradox

The following snippet is enough to reproduce my problem:
Either I set the thrown attribute public and get the error org.jboss.weld.exceptions.DefinitionException: WELD-000075: Normal scoped managed bean implementation class has a public field
Or I remove the public modifier and get the error org.junit.internal.runners.rules.ValidationError: The #Rule 'thrown' must be public.
I also tried to let the public modifier in place and to add the #Dependent annotation scope on the class, but got error org.jboss.weld.exceptions.DefinitionException: WELD-000046: At most one scope may be specified on [EnhancedAnnotatedTypeImpl] public #Dependent #ApplicationScoped #RunWith
I stripped out all unnecessary code, but this is quite a complex unit test with mock, service injection through CDI and some test methods thar are expected to throw an exception.
import org.jglue.cdiunit.CdiRunner;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
#RunWith(CdiRunner.class)
public class FooBarTest {
#Rule
public ExpectedException thrown = ExpectedException.none();
#Test
public void test() {
}
}
So my problem is that on one hand Weld wants all fields to not be public because it will not be able to proxify the class otherwise, and on the other hand, JUnit want Rule fields to be public because it is using reflection to access them and does not want to use the setAccessible(true) method because of the cases where the security manager is active. How to deal with that paradox?
NB: I also found a hint comments to this answer, stating that
You can also annotate a method with #Rule, so this would avoid the problem
But I could not found any example of junit test with a #Rule annotation on a method, I plan to ask a separate question about this.
I found out how to solve the problem. For future reference, here is a snippet that works, hope this will help other people.
import org.jglue.cdiunit.CdiRunner;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
#RunWith(CdiRunner.class)
public class FooBarTest {
private ExpectedException thrown = ExpectedException.none();
#Rule
public ExpectedException getThrown() {
return thrown;
}
#Test
public void test() {
thrown.expect(ArithmeticException.class);
int i = 1 / 0;
}
}

Cleanup after all junit tests

In my project I have to do some repository setup before all tests. This is done using some tricky static rules. However I've got no clue how to do clean up after all the tests. I don't want to keep some magic static number referring the number of all test methods, which I should maintain all the time.
The most appreciated way is to add some listener which would be invoked after all the tests. Is there any interface for it already in JUnit4?
edit: this has nothing to do with #BeforeClass and #AfterClass, cause I have to know if method annotated with #AfterClass is invoked for the last time.
I'm using JUnit 4.9. Will this help?:
import junit.framework.TestCase;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
#RunWith(Suite.class)
#SuiteClasses({First.class,Second.class,Third.class})
public class RunTestSuite extends TestCase {
#BeforeClass
public static void doYourOneTimeSetup() {
...
}
#AfterClass
public static void doYourOneTimeTeardown() {
...
}
}
Edit: I am quite positive (unless I misunderstand your question) that my solution is what you are looking for. i.e. one teardown method after all your tests have ran. No listener required, JUnit has this facility. Thanks.
I recommend to use org.junit.runner.notification.RunListener, example:
public class TestListener extends RunListener {
#Override
public void testRunStarted(Description description) throws Exception {
// Called before any tests have been run.
}
#Override
public void testRunFinished(Result result) throws Exception {
// Called when all tests have finished
}
}
Read more directly in JUnit java doc.
You can use that even with Maven's surefire (unit tests) plugin or failsafe plugin (integration tests) by adding following code into plugin configuration:
<properties>
<property>
<name>listener</name>
<value>com.innovatrics.afismq.it.TestListener</value>
</property>
</properties>
Just encountered the same problem.
My solution:
For a global set up: use (lazy) singleton to access something global that requires instantiation before the tests. The first test that accesses this singleton will trigger the global set up process.
For a global tear down: use a Java shutdown hook: Runtime.getRuntime().addShutdownHook(new Thread(() -> do_your_global_cleanup())));
You can always write your custom TestRunner. However, before you do that you need to evaluate the need for the same. It is better to use #BeforeClass and #AfterClass. Another example I can point to is, the fashion in which hibernate allows users to do unit testing using 'import.sql'.
No need to use suite, just add #BeforeClass, and #AfterClass as static
public class Tests {
#BeforeClass
public static void doYourOneTimeSetup()
{
...
}
#AfterClass
public static void doYourOneTimeTeardown() {
...
}
#Test
public void testYourTestcase()
{
...
}
}

Using assertArrayEquals in unit tests

My intention is to use assertArrayEquals(int[], int[]) JUnit method described in the API for verification of one method in my class.
But Eclipse shows me the error message that it can't recognize such a method. Those two imports are in place:
import java.util.Arrays;
import junit.framework.TestCase;
Did I miss something?
This would work with JUnit 5:
import static org.junit.jupiter.api.Assertions.*;
assertArrayEquals(new int[]{1,2,3},new int[]{1,2,3});
This should work with JUnit 4:
import static org.junit.Assert.*;
import org.junit.Test;
public class JUnitTest {
/** Have JUnit run this test() method. */
#Test
public void test() throws Exception {
assertArrayEquals(new int[]{1,2,3},new int[]{1,2,3});
}
}
This is the same for the old JUnit framework (JUnit 3):
import junit.framework.TestCase;
public class JUnitTest extends TestCase {
public void test() {
assertArrayEquals(new int[]{1,2,3},new int[]{1,2,3});
}
}
Note the difference: no Annotations and the test class is a subclass of TestCase (which implements the static assert methods).
This could be useful if you want to use just assertEquals without depending on your Junit version
assertTrue(Arrays.equals(expected, actual));
Try to add:
import static org.junit.Assert.*;
assertArrayEquals is a static method.
If you are writing JUnit 3.x style tests which extend TestCase, then you don't need to use the Assert qualifier - TestCase extends Assert itself and so these methods are available without the qualifier.
If you use JUnit 4 annotations, avoiding the TestCase base class, then the Assert qualifier is needed, as well as the import org.junit.Assert. You can use a static import to avoid the qualifier in these cases, but these are considered poor style by some.

Categories