There is a test:
package com.cdek.qa_auto.config;
import com.cdek.qa_auto.utils.CdekJUnitListener;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DynamicTest;
import org.junit.jupiter.api.TestFactory;
import org.junit.platform.launcher.Launcher;
import org.junit.platform.launcher.TestExecutionListener;
import org.junit.platform.launcher.core.LauncherFactory;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.junit.jupiter.api.DynamicTest.dynamicTest;
/***
*
*/
#SpringBootTest
public class JUnit5Test {
public JUnit5Test() throws Exception {}
#BeforeEach
public void beforeEach() throws Exception {
Launcher launcher = LauncherFactory.create();
TestExecutionListener listener = new CdekJUnitListener();
launcher.registerTestExecutionListeners(listener);
}
#TestFactory
public Stream<DynamicTest> test() throws Exception {
List<String> list = new ArrayList<>();
list.add("1");
list.add("12");
list.add("123");
list.add("1234");
list.add("12345");
return list.stream().map(item -> (
dynamicTest("test_" + item, () -> {
if ("1".equalsIgnoreCase(item)) {
System.out.println("fail");
fail("fail");
} else if ("12".equalsIgnoreCase(item)) {
assertTrue(false);
} else if ("123".equalsIgnoreCase(item)) {
throw new Exception("msg");
} else {
assertTrue(true);
}
}
)));
}
}
For example, make a screen for fallen tests.
Written implementation of import org.junit.platform.launcher.TestExecutionListener.
Connect so normally did not work. Does not go into executionFinished.
Basis: JUnit5-Maven-SpringBoot
How do execute specific code after each dynamic test?
As stated in the JUnit 5 User Guide:
The execution lifecycle of a dynamic test is quite different than it
is for a standard #Test case. Specifically, there are no lifecycle
callbacks for individual dynamic tests. This means that #BeforeEach
and #AfterEach methods and their corresponding extension callbacks are
executed for the #TestFactory method but not for each dynamic test. In
other words, if you access fields from the test instance within a
lambda expression for a dynamic test, those fields will not be reset
by callback methods or extensions between the execution of individual
dynamic tests generated by the same #TestFactory method.
Thus, you cannot use an #AfterEach method or one of the "after" lifecycle callback extensions (i.e., AfterEachCallback or AfterTestExecutionCallback).
Depending on what you are trying to achieve in your "listener", you may be able to accomplish that in a TestExecutionListener, but you cannot register that from within the test class. See Plugging in your own Test Execution Listener in the User Guide for details.
Related
I am trying to setup Junit, but just can't seem to, primarily because my use case is not basic (tho my skill level is).
I was given a jar as part of an assignment, and I can run the program without issue. However, I am unable to set it up properly in eclipse, such that it runs. The main method is in the jar package, so I cannot see it to give more information about it.
Here is my derived class that I would like to test.
package jimmy.kilmer.com;
import java.awt.Color;
import jarPackageImports.AI;
import jarPackageImports.MovementAction;
import jarPackageImports.GameInfo;
import jarPackageImports.PlayerAction;
public class GameAI extends AI {
public gameAI(Info info) {
super(info);
}
public Color getColor() {
return Color.MAGENTA;
}
public String getName() {
return "Usain Bolt";
}
public PlayerAction update() {
// TODO game movement actions
// all available methods not listed here...
info.getVelocity();
info.getX();
info.getY();
MovementAction steeringBehavior = null;
return steeringBehavior;
}
public int[][] populateAllPossibleNodes() {
int[][] allPossibleNodes = new int[screenWidth/20][screenHeight/20];
return allPossibleNodes;
}
}
I have tried various different ways to instantiate an object in junit for it to run, but I simply cannot, and thus I can only test static method -- which isn't so useful.
This is what the template looks like.
package jimmy.kilmer.com;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
class GameKITest {
private Info info;
private GameAI gameAiInstance = new GameAI((jarPackageImports.Info) Info info);
#BeforeAll
static void setUpBeforeClass() throws Exception {
}
#AfterAll
static void tearDownAfterClass() throws Exception {
}
#BeforeEach
void setUp() throws Exception {
}
#AfterEach
void tearDown() throws Exception {
}
#Test
void testPopulateAllPossibleNodes() {
// 1. given/arrange
int[][] array1 = new int[80][65];
// 2. when/act
int[][] array2 = GameAiInstance.populateAllPossibleNodes();
// 3. then/assert
assertArrayEquals(array1, array2);
}
}
There is something unbasic about the jar setup, such that I cannot simply create an object, the Info, which I don't have more information about, seems to be the problem. I thought it was a type of Java type? But, I couldn't find anything, so it must be a user create/enumerated type.
Any help to be able to develop this code in a TDD way, instead of just hacking in the derived class is my goal.
The above code will compile (not have errors in eclipse), but it returns NullPointerException: cannot invoke "jarPackageImports.Info.getScene()" because "this.info" is null.
If my understanding is correct, that means that I am not passing or setting up the info variable as it's supposed to be.
Normally you have to use an instance of your Class you want to test.
package jimmy.kilmer.com;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;
class GameKITest {
private GameKI gameKi = new GameKI(new Info());
#Test
void getName() {
String actual = gameKi.getName();
assertEquals("Usain Bolt", actual);
}
}
If you can not create an instance of needed dependencies, you could mock It by Mockito.
package jimmy.kilmer.com;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;
#ExtendWith(MockitoExtension.class)
class GameKITest {
#Mock
private Info info;
private GameKI gameKi = new GameKI(info);
#Test
void getName() {
Mock.when(info.getVelocity()).thenReturn(result);
String actual = gameKi.update();
assertEquals("Usain Bolt", actual);
}
}
I have a strange problem. I've written my API and I just wanted to test it.
I wrote a simple test code by using Restassured:
package com.example.restservicetest;
import io.restassured.RestAssured;
import io.restassured.response.Response;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.web.server.LocalServerPort;
import java.util.*;
#SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class RestServiceTestApplicationTests {
#LocalServerPort
private int port;
private Response response;
private List<Object> folderList;
#Test
public void getWholeFolders() {
response = RestAssured.given().port(port).when().get("/api/opening").then().statusCode(200).extract().response();
folderList= response.jsonPath().getList("folders");
}
#Test
public void getRandomFolderNumber() {
Random rand = new Random();
RestAssured.given().port(port).when().get("/api/opening/folder/" + rand.nextInt(folderList.size()-1)).then().statusCode(200);
}
}
When I debug my test, at the end of first getWholeFolders test, I see that folderList is not empty as I expected. My whole folder list is assigning to it.
But when the time is for 2nd test getRandomFolderNumber, I see that folderList becomes null.
Why does it become null?
As Andriy mentiond in comment, JUnit Jupiter will use a default lifecycle mode, it means JUnit creates a new instance of each test class before executing each test method TestInstance.Lifecycle.PER_METHOD.
To change that, you change PER_METHOD --> PER_CLASS (basically means one instance of test class for all test method).
One more subtle thing, you need to set order for test method to make sure getRandomFolderNumber always run after getWholeFolders
#TestInstance(TestInstance.Lifecycle.PER_CLASS)
#TestMethodOrder(MethodOrderer.OrderAnnotation.class)
class RestServiceTestApplicationTests {
...
#Test
#Order(1)
public void getWholeFolders() {
...
}
#Test
#Order(2)
public void getRandomFolderNumber() {
...
}
}
I realize there are many many very similar questions. I've been through all of them and I still cannot make my code work.
I have a service defined in my Spring-Boot application, just like this:
#Service
public class FileStorageService {
private final Path fileStorageLocation;
#Autowired
public FileStorageService(final FileStorageProperties fileStorageProperties) {
//FileStorageProperties is a very simple class that right now just holds one String value
this.fileStorageLocation = Paths.get(fileStorageProperties.getUploadDir())
.toAbsolutePath()
.normalize();
try {
Files.createDirectories(fileStorageLocation);
} catch (IOException e) {
// FileStorageException is my custom, runtime exception
throw new FileStorageException("Failed to create directory for stored files", e);
}
}
}
And I want to test scenario, when directory creation fails and thus I need to mock method Files.createDirectories(). My test class looks like this:
import org.junit.Test;
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;
import java.io.IOException;
import java.nio.file.Files;
#RunWith(PowerMockRunner.class)
#PrepareForTest({Files.class})
public class FileStorageServiceTest {
private static final String UPLOAD_DIR = "uploadDir";
#Test(expected = FileStorageException.class)
public void some_test() throws IOException {
PowerMockito.mockStatic(Files.class);
PowerMockito.when(Files.createDirectories(Mockito.any())).thenThrow(new IOException());
new FileStorageService(createFileStorageProperties());
}
private FileStorageProperties createFileStorageProperties() {
final FileStorageProperties fileStorageProperties = new FileStorageProperties();
fileStorageProperties.setUploadDir(UPLOAD_DIR);
return fileStorageProperties;
}
}
I believe I followed every step from tutorials and questions I've read.
I use:
#RunWith(PowerMockRunner.class),
#PrepareForTest({Files.class}),
PowerMockito.mockStatic(Files.class),
and PowerMockito.when(Files.createDirectories(Mockito.any())).thenThrow(new IOException());.
Still, no exception is thrown during test and it fails. WIll be super thankful for the help, cause I feel I miss something really simple and just cannot see it.
From: https://github.com/powermock/powermock/wiki/Mock-System
Normally you would prepare the class that contains the static methods (let's call it X) you like to mock but because it's impossible for PowerMock to prepare a system class for testing so another approach has to be taken. So instead of preparing X you prepare the class that calls the static methods in X!
Basically, we mock the class's use of the System class, rather than unmockable System class itself.
#PrepareForTest({Files.class})
An alternative, non-Powermock way to do this without mocking any system class would be to create a helper method, #Spy the original class, and mock that helper method specifically to throw the exception.
when(spy.doSomethingWithSystemClasses()).thenThrow(new Exception("Foo");
Requirement: Read custom annotation details and generate report for all test classes of all suites.
Tried Solution:
Implemented custom listener using ITestListener. But don't see direct way to get custom annotation details used as part of test methods apart from below way.
#Override
public void onStart(ITestContext context) {
ITestNGMethod[] testNGMethods = context.getAllTestMethods();
for (ITestNGMethod testNgmethod : testNGMethods) {
Method[] methods = testNgmethod.getRealClass().getDeclaredMethods();
for (Method method : methods) {
if (method.isAnnotationPresent(MyCustomAnnotation.class)) {
//Get required info
}
}
}
}
Inner loop triggers almost n*n(number of methods) times for each test class. I can control it by adding conditions.
As I'm new bee to TestNG framework, would like to know the better solution to achieve my requirement i.e. generating report by reading custom annotation details from all test methods from all suites.
Here's how you do it.
I am using the latest released version of TestNG as of today viz., 7.0.0-beta3 and using Java8 streams
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import org.testng.ITestContext;
import org.testng.ITestListener;
import org.testng.ITestNGMethod;
public class MyListener implements ITestListener {
#Override
public void onStart(ITestContext context) {
List<ITestNGMethod> methodsWithCustomAnnotation =
Arrays.stream(context.getAllTestMethods())
.filter(
iTestNGMethod ->
iTestNGMethod
.getConstructorOrMethod()
.getMethod()
.getAnnotation(MyCustomAnnotation.class)
!= null)
.collect(Collectors.toList());
}
#Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
#Target({METHOD, TYPE})
public static #interface MyCustomAnnotation {}
}
I'm new to jMock, so I'm trying it out on a simple example. I can't figure out why it's not working, though. Here's the class that I'm testing:
package com.application;
import com.domain.Coordinate;
import com.domain.Playable;
public class ChessFacade {
private final Playable board;
public ChessFacade(Playable aBoard) {
board = aBoard;
}
public void showPotentialMoves(Coordinate aCoordinate) {
board.getTileOccupancy(aCoordinate);
}
}
And here's my Mock Object test:
package unit.application;
import application.ChessFacade;
import com.domain.Coordinate;
import com.domain.Playable;
import junit.framework.TestCase;
import org.jmock.Expectations;
import org.jmock.Mockery;
import org.jmock.integration.junit4.JMock;
import org.jmock.integration.junit4.JUnit4Mockery;
import org.junit.runner.RunWith;
#RunWith(JMock.class)
public class ChessFacadeTest extends TestCase {
public void testFacadeGetsPotentialMovesFromBoard() {
Mockery context = new JUnit4Mockery();
final Playable mockBoard = context.mock(Playable.class);
ChessFacade facade = new ChessFacade(mockBoard);
final Coordinate locationToShow = new Coordinate(0, 0);
facade.showPotentialMoves(locationToShow);
context.checking(new Expectations() {{
oneOf(mockBoard).getTileOccupancy(locationToShow);
}});
context.assertIsSatisfied();
}
}
The error I'm receiving is:
Testcase: testFacadeGetsPotentialMovesFromBoard(unit.application.ChessFacadeTest): Caused an ERROR
unexpected invocation: playable.getTileOccupancy(<Coordinate{row=0column=0}>)
no expectations specified: did you...
- forget to start an expectation with a cardinality clause?
- call a mocked method to specify the parameter of an expectation?
what happened before this: nothing!
java.lang.AssertionError: unexpected invocation: playable.getTileOccupancy(<Coordinate{row=0column=0}>)
no expectations specified: did you...
- forget to start an expectation with a cardinality clause?
- call a mocked method to specify the parameter of an expectation?
what happened before this: nothing!
at org.jmock.internal.InvocationDispatcher.dispatch(InvocationDispatcher.java:56)
at org.jmock.internal.InvocationDispatcher.dispatch(InvocationDispatcher.java:56)
at org.jmock.Mockery.dispatch(Mockery.java:218)
at org.jmock.Mockery.access$000(Mockery.java:43)
at org.jmock.Mockery$MockObject.invoke(Mockery.java:258)
at org.jmock.internal.InvocationDiverter.invoke(InvocationDiverter.java:27)
at org.jmock.internal.FakeObjectMethods.invoke(FakeObjectMethods.java:38)
at org.jmock.lib.JavaReflectionImposteriser$1.invoke(JavaReflectionImposteriser.java:33)
at $Proxy0.getTileOccupancy(Unknown Source)
at application.ChessFacade.showPotentialMoves(ChessFacade.java:15)
at unit.application.ChessFacadeTest.testFacadeGetsPotentialMovesFromBoard(ChessFacadeTest.java:22)
You might have to define your expectations before you call the facade method instead of after.
Also, you appear to be mixing JUnit 3 and 4. I suggest you just go with one. The #RunWith(JMock.class) is for 4, otherwise you need to the TestCase class that comes with JMock's JUnit 3 integration.