How to load a different resource with different unit test methods? - java

I have about 15 JUnit test cases each one which needs a difference resource file from which it reads necessary input data. Currently, I'm hard coding the specific resource file path in each test case method.
#Test
public void testCase1() {
URL url = this.getClass().getResource("/resource1.txt");
// more code here
}
#Test
public void testCase2() {
URL url = this.getClass().getResource("/resource2.txt");
// more code here
}
May be I could have all these files loaded in the setUp() method into separate URL variables and then use the specific URL variable in each test method. Is there a way better way of doing this?

You can use the TestName rule.
#Rule public TestName testName = new TestName();
public URL url;
#Before
public void setup() {
String resourceName = testName.getMethodName().substring(4).toLowerCase();
url = getClass().getResource("/" + resourceName + ".txt");
}
#Test
public void testResource1() {
// snip
}
#Test
public void testResource2() {
// snip
}

Try JUnit RunWith(Parameterized.class).
Example, that takes a resource name and an int expected result :
#RunWith(Parameterized.class)
public class MyTest {
#Parameterized.Parameters
public static Collection<Object[]> data() {
return Arrays.asList(new Object[][]{
{"resource1.txt", 0000}, {"resource2.txt", 9999}
});
}
public final URL url;
public final int expected;
public MyTest(String resource, int expected) {
this.url=URL url = this.getClass().getResource("/"+resource)
this.expected = expected;
}
#Before
public void setUp() {
}
#Test
public void testReadResource() throws Exception {
// more code here, based on URL and expected
}
}
More info here:http://junit.org/apidocs/org/junit/runners/Parameterized.html

Related

Unit test with JUnit 5

Hi all i receive Nullpointer when trying to execute this unit test.I want to test e class which receive 3 parameters and returns a string. I think i need to make #Before or something else but it didn't works. Do you have suggestions...Thanks !
public class UrlConstructorTest {
private UrlConstructor urlConstructor;
#Before
public void setUp() {
urlConstructor = new UrlConstructor();
}
public static final String TEST_UPDATE_MANIFEST_SR = "/packages/proxyId/test/test1/123/test3/test_test";
#Test
public void constructUpdateManifestSrInSasTokenTest() {
String result = urlConstructor.composeDeviceRegistrationUrl("test","test123","test");
System.out.println(result);
assertNotNull(result);
assertEquals(TEST, result);
}
}
UrlConstructor is define like this:
#Component
public class UrlConstructor {
And this is the method in this class:
public String composeDUrl(String deviceId, String scopeId) {
return String.format(Constants.socpe, tes, test);
}
In Junit5, you should be using #BeforeEach. Or you can get rid of that setUp method completely.
public class UrlConstructorTest {
private final UrlConstructor urlConstructor = new UrlConstructor();
public static final String TEST_SR = "/packages/proxyId/testID/product/testscope/testcomponent/coomponent_up";
#Test
public void constructTest() {
String result = urlConstructor.composeDeviceRegistrationUrl("testID","coomponent_up","testscope");
System.out.println(result);
assertNotNull(result);
assertEquals(TEST_SR, result);
}
}

Error: Static mocking is already registered in the current thread

Junit test case getting failed:
existing static mocking registration must be deregistered
Test class:
#RunWith(MockitoJUnitRunner.class)
public class DeleteReportServiceTest {
#InjectMocks
private ReturnCheckController returnCheckController;
#Mock
MockedStatic<DigitalGatewayRESTClient> mockDigiGateway;
#Before
public void setUp() throws Exception {
this.returnCheckController = new ReturnCheckController();
this.mockDigiGateway = Mockito.mockStatic(DigitalGatewayRESTClient.class);
}
#Test
public void testdeleteReport() throws Exception {
String input = "{\"clientId\": \"1\", \"applicationId\": \"9010\"}";
String response = "{\"success\":true,\"successText\":\"Manual adjustment record deleted\"}";
String expected = "{\"status\":200}";
JSONObject returnJson = new JSONObject(response);
mockDigiGateway.when((Verification) DigitalGatewayRESTClient.getDGRESTConnection(Mockito.any())).thenReturn(returnJson);
String actual = returnCheckController.deleteReport(input);
Assert.assertNotNull(actual);
Assert.assertEquals(expected, actual);
}
#After
public void after() {
mockDigiGateway.close();
}
}
Closing the static mocking still am getting the error.
You can NOT use #Mock and MockedStatic at same time.
Instead, if you want to stub static method of DigitalGatewayRESTClient, you should create a MockedStatic<DigitalGatewayRESTClient> additionally, like this:
private MockedStatic<DigitalGatewayRESTClient> mockedStaticDigiGateway;
Then initialize mockedStaticDigiGateway:
#Before
public void setUp() throws Exception {
this.mockedStaticDigiGateway = Mockito.mockStatic(DigitalGatewayRESTClient.class);
// other setup...
}
and modify your test case, stub mockedStaticDigiGateway.when... instead:
#Test
public void testdeleteReport() throws Exception {
// arrange ...
mockedStaticDigiGateway.when((Verification) DigitalGatewayRESTClient.getDGRESTConnection(Mockito.any()))
.thenReturn(returnJson);
// assert...
}
Finally, close mockedStaticDigiGateway after test is finished:
#After
public void after() {
mockedStaticDigiGateway.close();
}
I think it will work correctly although one year passed.

parameterized test to check if constructor throws exception

I have a constructor that may throw an IOException:
public MyClass(string url) throws IOException { ... }
Now I want to test of the exception is thrown in certain scenarios using a parameterized test. Can I annotate my test-method with a value for url and the expected exception, something like this?
#Test("https://myHost/not.existsing", expected = IOException.class)
#Test("https://myHost/whrong.fileextension", expected = IOException.class)
public void MyTest(String url)
{
Assert.Throws(expected);
}
Junit 4 supports Prameterized. Try this:
#RunWith(Parameterized.class)
public class Test {
#Parameters
public static Collection<Object[]> data() {
return Arrays.asList(new Object[][] {
{ "https://myHost/whrong.fileextension" },
{ "https://myHost/not.existsing"}
});
}
private String url;
public Test(String url) {
this.url = url;
}
#Test(expected = IOException.class)
public void test() throws IOException {
MyClass myClass = new MyClass(url);
}
}

junit4 creating test suite with specific test methods

In junit4 I want to execute specific test methods from different classes i.e want create a test suite with specific test methods from different classes.
Lets say I have 2 classes:
public class Test_Login {
#Test
public void test_Login_001(){
System.out.println("test_Login_001");
}
#Test
public void test_Login_002(){
System.out.println("test_Login_002");
}
#Test
public void test_Login_003(){
System.out.println("test_Login_003");
}
}
public class Logout {
#Test
public void test_Logout_001(){
System.out.println("test_Logout_001");
}
#Test
public void test_Logout_002(){
System.out.println("test_Logout_002");
}
#Test
public void test_Logout_003(){
System.out.println("test_Logout_003");
}
}
From the above classes I want to execute test methods test_Login_001 , test_Login_003 , test_Logout_002 only.
How this can be achieved in junit4 ?
Since JUnit 4.8 introduced Categories there exists a clean solution, create a TestSuite:
#RunWith(Categories.class)
#IncludeCategory(MustHaveTests.class)
#SuiteClasses( { Test_Login.class, Test_Logout.class })
public class MustHaveTestsTestSuite {
public interface MustHaveTests { /* category marker */ }
}
And add the #Category(MustHaveTests.class) above every test you would like to run with the TestSuite, e.g.:
#Category(MustHaveTests.class)
#Test
public void test_Login_001(){
System.out.println("test_Login_001");
}
When running the TestSuite only the MustHaveTests-"tagged" tests will be executed. More Details on #Category: https://github.com/junit-team/junit4/wiki/categories
You need to create an org.junit.runner.Request and pass it to the JunitCore runner, or actually to any Runner.
JUnitCore junitRunner = new JUnitCore();
Request request = Request.method(Logout.class, "test_Logout_002");
Result result = junitRunner.run(request);
I actually created an Annotation and can search for methods with those annotations and dynamically create Request and run them
public class TestsSuite {
public static void main(String[] args) throws Exception {
Class annotation = MyTestAnnotation.class;
JUnitCore junitRunner = new JUnitCore();
Class testClass = Test_Login.class;
Method[] methods = testClass.getMethods();
for (Method method : methods) {
if (method.isAnnotationPresent(annotation)) {
if (method.isAnnotationPresent(org.junit.Test.class)) {
Request request = Request.method(testClass, method.getName());
Result result = junitRunner.run(request);
System.out.println(result.wasSuccessful());
}
}
}
}
}
This might not be the slickest implementation, but I solved a similar problem by created a new #SuiteMethods annotation as follows:
SuiteMethods.java
#Retention(RUNTIME)
#Target(TYPE)
public #interface SuiteMethods {
String[] value() default {""};
}
FilteredSuite.java
public class FilteredSuite extends Categories {
private static String[] TEST_METHODS_TO_RUN = {""}; // default behavior is to run all methods
private static Class<?> extractMethodNamesFromAnnotation(Class<?> clazz) {
SuiteMethods methodsAnnotation = clazz.getAnnotation(SuiteMethods.class);
if (methodsAnnotation != null) {
// if our MethodsAnnotation was specified, use it's value as our methods filter
TEST_METHODS_TO_RUN = methodsAnnotation.value();
}
return clazz;
}
public static Filter getCustomFilter() {
Filter f = new Filter() {
#Override
public boolean shouldRun(Description desc) {
String methodName = desc.getMethodName();
for (String subString : TEST_METHODS_TO_RUN) {
if (methodName == null || methodName.contains(subString)) {
return true;
}
}
return false;
}
#Override
public String describe() {
return null;
}
};
return f;
}
public FilteredSuite(Class<?> arg0, RunnerBuilder arg1) throws InitializationError {
super(extractMethodNamesFromAnnotation(arg0), arg1);
}
#Override
public void filter(Filter arg0) throws NoTestsRemainException {
// At test suite startup, JUnit framework calls this method to install CategoryFilter.
// Throw away the given filter and install our own method name filter
super.filter(getCustomFilter());
}
}
A Usage Example
#RunWith(FilteredSuite.class)
#SuiteClasses({
GroupRestTest.class,
ScenarioRestTest.class
})
#SuiteMethods({
"testReadOnlyFlag",
"testSheetWriteData",
"testAddScenarioMeta"
})
public class SubsetTestSuite {
}

How to obtain test case name in JUnit 4 at runtime? [duplicate]

This question already has answers here:
Get name of currently executing test in JUnit 4
(17 answers)
Closed 9 years ago.
I want to do some logging while executing my JUnit test. In JUnit 3.x it was always easy to obtain the name of the currently running test case, no matter how the test case was instantiated:
public void testFoo() throws Exception() {
String testName = this.getName();
// [...] do some stuff
}
In JUnit 4 things seem to be not so easy. Does anyone know a solution to this? Is there any option to reflect into the current Runner instance?
In JUnit 4.7, you can also get the name of the currently executed test method. May be nice when logging.
Taken from JUnit 4.7 Release Notes (read them here at github) :
public class NameRuleTest {
#Rule public TestName name = new TestName();
#Test public void testA() {
assertEquals("testA", name.getMethodName());
}
#Test public void testB() {
assertEquals("testB", name.getMethodName());
}
}
OK. I've found another approach [somewhere on the Internet](http://www.nabble.com/What-happened-to-getName()--td23456371.html):
#RunWith(Interceptors.class)
public class NameTest {
#Interceptor public TestName name = new TestName();
#Test public void funnyName() {
assertEquals("funnyName", name.getMethodName());
}
}
public class FooTest {
#Rule
final public TestRule traceTestWatcher = new TestWatcher() {
#Override
protected void starting(Description d) {
System.out.println(d);
}
};
#Test
public void testBar() {
...
}
#Test
public void testBaz() {
...
}
}
What's wrong with:
#Test
public void foo() throws Exception() {
String testName = this.getName();
// [...] do some stuff
}
?
I know this is old, but here is a useful (non-junit) method that I put at the top of all my tests.
public static void printTestName(){
final StackTraceElement[] ste = new Throwable().getStackTrace();
int buffer = 35 - ste[1].getMethodName().length();
System.out.println("*******************************************************");
System.out.println("* TEST: " + ste[1].getMethodName() + getBuffer(buffer) + "*");
System.out.println("*******************************************************");
}
private static String getBuffer(int offset){
StringBuilder buffer = new StringBuilder("");
for(int i = 1; i < offset; i++){
buffer.append(" ");
}
return buffer.toString();
}

Categories