Java Test Runner in Visual Studio Code - java

I recently started to use Visual Studio Code for java development. I am having some problems with the test runner.
I can run main() in .java files without any issues, but the "run test" option does not show up in my JUnit test file. Also, no files show up in the Test runner side-bar.
Screenshot 1
Screenshot 2
This is the JUnit test file for a Student class.
import static org.junit.Assert.*;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.Ignore;
class Student_test {
#Test
public void testGetName() {
Student john = "John Deer";
String expected = "John Deer";
String result = john.getName();
assertEquals(result, expected);
}
}
I use the Java Test Runner extension in VS Code:
https://marketplace.visualstudio.com/items?itemName=vscjava.vscode-java-test
Does anyone know how I could get the test file to show the "run test" option in the file, or how I could find it in the side-bar?

I believe the folder you are placing your tests is wrong. For the folder to be recognized.
Try to set test directory in maven
e.g.
<build>
<testSourceDirectory>${basedir}/src/test/</testSourceDirectory>
</build>

Related

Unable to run a cucumber feature within IntelliJ

I have a feature with a number of steps but the first one is the only working and the rest are working fine. Now when I add new steps to the same feature there not working either its very confusing. Its lis like half the feature is working but the other half is no working.
Please see test runner below:
import io.cucumber.junit.Cucumber;
import io.cucumber.junit.CucumberOptions;
import org.junit.runner.RunWith;
#RunWith(Cucumber.class)
#CucumberOptions(features = "src/test/java/features", glue = {"stepDefinitions"})
public class TestRunner {
}
Folder structure:
Error message:
You can implement this step using the snippet(s) below:
#Given("Add Place Payload with {string} {string} {string}")
public void add_place_payload_with(String string, String string2, String string3) {
// Write code here that turns the phrase above into concrete actions
throw new io.cucumber.java.PendingException();
}
I am also getting a red exclamation mark on the feature:

Unable to run any Junit4 tests - InvalidTestClassError: Invalid test class

I am trying to run Junit4 tests and I am unable to run it. I have the following dependency installed
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
My test class looks like this
package model.validators;
import org.junit.Assert;
import org.junit.Test;
import java.util.Arrays;
import java.util.List;
class UserValidatorTest {
#Test
public void shouldReturnTrueForValidPhoneNumbers() {
List<String> phoneNumbers = Arrays.asList(
"9876543210",
"7777543210"
);
boolean result = UserValidator.validateUserPhoneNumbers(phoneNumbers);
Assert.assertTrue(result);
}
}
When I try to run this test, I get the following error
org.junit.runners.model.InvalidTestClassError: Invalid test class 'model.validators.UserValidatorTest':
I am using IntellijIdea. Any idea what is going wrong here ? TIA
Tried changing dependencies, reloading maven project, setting the correct classpath in Junit Run configurations
I can see that your class UserValidatorTest is not public. On making your class public, you will be able to run the tests.
package model.validators;
import org.junit.Assert;
import org.junit.Test;
import java.util.Arrays;
import java.util.List;
public class UserValidatorTest {
#Test
public void shouldReturnTrueForValidPhoneNumbers() {
List<String> phoneNumbers = Arrays.asList(
"9876543210",
"7777543210"
);
boolean result = UserValidator.validateUserPhoneNumbers(phoneNumbers);
Assert.assertTrue(result);
}
}
JUnit4 requires everything to be public.
JUnit5 is more tolerant regarding the visibilities of Test classes (Test classes, test methods, and lifecycle methods are not required to be public, but they must not be private).
SonarLint Rule description:
In this context (JUnit5), it is recommended to use the default package visibility, which improves the readability of code.

Display a user-friendly message when JUnit tests fails

I got the message like this.
com.controller.Test1 > test FAILED
java.lang.NoSuchMethodError at Test1.java:18
The dependencies for test compiling is
testCompile "junit:junit:4.11",
'org.mockito:mockito-all:1.10.19',
'com.jayway.jsonpath:json-path:2.2.0',
'org.hamcrest:hamcrest-all:1.3',
'org.flywaydb.flyway-test-extensions:flyway-dbunit-spring4-test:4.0'
And this is my test code.
package com.controller;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.runners.MockitoJUnitRunner;
import static org.hamcrest.Matchers.instanceOf;
import static org.junit.Assert.assertThat;
#RunWith(MockitoJUnitRunner.class)
public class Test1 {
#Test
public void test(){
assertThat(Long.valueOf(1), instanceOf(Integer.class));
}
}
I want the message like this.
Expected: an instance of java.lang.Integer
but: <1L> is a java.lang.Long
The java.lang.NoSuchMethodError is not related to JUnit specifically. Instead, it indicates that the version of a class that was on your compiler's classpath is different from the version of the class that is on your runtime classpath.
The reason for the clash is that JUnit comes with its own org.hamcrest.Matcher class that is being used instead of the one imported in your code. Use mockito-core in your imports instead of mockito-all to exclude the matcher.

Main class run with exception in thread error with JUnit

I'm using the crimson editor along with the command prompt console for compiling and running the programs. I've just installed and am new to JUnit. Currently, I'm following a basic tutorial from TutorialsPoint.com and have followed the steps setting the classpath.
The link to the tutorial is available here:
http://www.tutorialspoint.com/junit/junit_environment_setup.htm
From this tutorial, there's an ending part whereby you will asked to create class files to test the JUnit. Eventually, after compiling, I tried to run the main class but I was presented with a long series of errors so I was hoping you guys can help me out here.
import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class TestJunit {
#Test
public void testAdd() {
String str= "Junit is working fine";
assertEquals("Junit is working fine",str);
}
}
Main class:
import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
import org.junit.runner.notification.Failure;
public class TestRunner {
public static void main(String[] args) {
Result result = JUnitCore.runClasses(TestJunit.class);
for (Failure failure : result.getFailures()) {
System.out.println(failure.toString());
}
System.out.println(result.wasSuccessful());
}
}
And the screenshot of the console displaying the error:
Try to add hamcrest-core-1.3.jar to your classpath.
Download the jar from Hamcrest site: https://code.google.com/p/hamcrest/
Assert class of JUnit need Hamcrest matchers.
The answer to my problem with the help of Mark A.Fitzgerald and pz74 is that my CLASSPATH value was setted wrongly. I have amended it to C:\JUnit\junit-4.12.jar;C:\HAMCREST\hamcrest-core-1.3.jar; and hamcrest had to be installed as well.

PowerMock ECLEmma coverage issue

We are using EasyMock and PowerMock with JUnit. The coverage tool used is ECLEmma. With EasyMock, it shows the coverage properly in green (as covered). However, for the code that is unit tested with PowerMock, the coverage is shown in red (uncovered). Have read similar questions on the web. However, just wanted to check if there is a solution for this.
Thanks
Venkatesh
Yes, there is a solution for this:
First you will have to add this maven dependency:
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4-rule-agent</artifactId>
<version>1.6.4</version>
<scope>test</scope>
</dependency>
Then, instead of using this annotation #RunWith(PowerMockRunner.class), just add a #Rule in the Test class like this:
public class Test {
#Rule
public PowerMockRule rule = new PowerMockRule();
you can find more in this blog Make EclEmma test coverage work with PowerMock
It's a known problem : https://github.com/jayway/powermock/issues/422
And it has been for a long time, it won't be fixed anytime soon.
I suggest you use eCobertura instead.
This has worked in most cases in my project:
#Rule
public PowerMockRule rule = new PowerMockRule();
static {
PowerMockAgent.initializeIfNeeded();
}
Remove/Comment #RunWith(PowerMockRunner.class) & include following imports after adding powermock-module-javaagent-1.6.5.jar in your classpath:
import org.junit.Rule;
import org.powermock.modules.junit4.rule.PowerMockRule;
import org.powermock.modules.agent.PowerMockAgent;
Now right click->Coverage As->Coverage Configurations and add following lines in Arguments:
-ea -noverify -javaagent:path/to/powermock-module-javaagent-1.6.5.jar
Click Apply->Coverage.
Also note that #Before would not work in this case so you have to add all the stuffs in the methods marked with #Test from the method marked with #Before.
We have a static classes to mock. With mocking static classes, eclEmma code coverage plugin is not working in Eclipse. So what we did is, so placed #RunWith(JUnit4.class) (Instead of #RunWith(PowerMockRunner.class) ) before class and placed following lines inside class
static {
PowerMockAgent.initializeIfNeeded();
}
#Rule
public PowerMockRule rule = new PowerMockRule();
Compiled the class and ran the test class. Code coverage is working for class. This change is only in Eclipse IDE.
After writing test cases, we reverted code back to normal. Placed #RunWith(PowerMockRunner.class) instead of #RunWith(JUnit4.class) and commented above static code and powermockrule lines.
I have managed to generate PowerMock coverage with Jacoco, using powermock-module-javaagent.
Just make sure you put powermock agent after jacoco agent:
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<useSystemClassLoader>true</useSystemClassLoader>
<argLine>${jacocoArgLine} -javaagent:${settings.localRepository}/org/powermock/powermock-module-javaagent/${powermock.version}/powermock-module-javaagent-${powermock.version}.jar -noverify</argLine>
...
If you want to see an example, take a look at this project: https://github.com/jfcorugedo/sonar-scanner
Here you can see that sonar takes into account static methods and new statements mocked by PowerMock:
If you want to mock newstatements make sure you use PowerMockRule instead of PowerMockRunner.
Take a look at this test
Updating powermock version fix my issue below is maven dependency of supported version
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4-rule-agent</artifactId>
<version>1.7.3</version>
<scope>test</scope>
</dependency>
Hope this helps !!!
I was facing the same issue. So, I updated the powerMockito version. Now I am using Power mock version 1.7.4 and Jacoco version 0.8.5. It's even working on eclipse also.
Here is some more detailed answer with full class.
couple of points to note:
I had to use spy instead of mockStatic
I had to move #PrepareForTest to method level.
As someone mentioned in other answers I also had to add following dependency
org.powermock:powermock-module-junit4-rule-agent:2.0.9
Below is my full class code for reference:
import java.util.ArrayList;
import java.util.Arrays;
import org.elasticsearch.action.ActionFuture;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.support.IndicesOptions;
import org.elasticsearch.client.Client;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.agent.PowerMockAgent;
import org.powermock.modules.junit4.rule.PowerMockRule;
import org.opensource.dummy.config.DummyConfig;
import org.opensource.dummy.data.builder.DataBuilder;
import org.opensource.dummy.model.SampleRequest;
import org.opensource.dummy.model.SampleType;
import org.opensource.dummy.model.Item;
import org.opensource.dummy.model.RequestType;
#RunWith(JUnit4.class)
public class MockedDataSearchServiceHelperTest {
static {
PowerMockAgent.initializeIfNeeded();
}
#Rule
public PowerMockRule rule = new PowerMockRule();
#PrepareForTest({ DummyConfig.class })
#SuppressWarnings("unchecked")
#Test
public void testSearchResponseValid() throws Exception {
Item Item = DataBuilder.createItem("2024-01-24", "2024-12-25", "61ef8faebec3bb72fbcf336d", null);
SampleRequest sampleRequest = DataBuilder.createSampleRequest(Arrays.asList(Item),
DataBuilder.createDeliveryMetrics(1), null, RequestType.ITEM);
BoolQueryBuilder boolQueryBuilder = DataSearchServiceHelper.createCustomQuery(sampleRequest, Item);
SearchRequestBuilder searchRequestBuilder = PowerMockito.mock(SearchRequestBuilder.class);
ActionFuture<SearchResponse> actionFuture = PowerMockito.mock(ActionFuture.class);
Client client = PowerMockito.mock(Client.class);
PowerMockito.spy(DummyConfig.class);
PowerMockito.doReturn(client).when(DummyConfig.class, "getClient");
Mockito.when(client
.prepareSearch(new String[] { "dummy" }))
.thenReturn(searchRequestBuilder);
Mockito.when(searchRequestBuilder.setIndicesOptions(IndicesOptions.LENIENT_EXPAND_OPEN))
.thenReturn(searchRequestBuilder);
Mockito.when(searchRequestBuilder.setQuery(Mockito.any(QueryBuilder.class))).thenReturn(searchRequestBuilder);
Mockito.when(searchRequestBuilder.execute()).thenReturn(actionFuture);
Mockito.when(actionFuture.actionGet()).thenReturn(new SearchResponse(null, null, 0, 0, 0, 0, null, null));
SearchResponse searchResponse = DataSearchServiceHelper.getSearchResponse(
new String[] { "dummy" },
boolQueryBuilder, DataBuilder.createDeliveryMetrics(1), RequestType.ITEM);
Assert.assertNotNull(searchResponse);
}
}
I hope this helps to someone.
For mocking static classes, using #RunWith(PowerMockRunner.class) and running the "Coverage As JUnit Test" on Eclipse does show covered code as uncovered and it clearly does seem like an issue.
To add to the solutions above, in a maven project, you can try this..
In the root pom.xml, for report generation, add html as a format in cobertura-maven-plugin. Below is the way it looks.
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>cobertura-maven-plugin</artifactId>
<configuration>
<formats>
<format>html</format>
<format>xml</format>
</formats>
</configuration>
</plugin>
Then, go to the module where your class resides and open target/site/cobertura/index.html file in Eclipse Web Browser or in the one of your choice. You can find the coverage information there.

Categories

Resources