Explore topic-wise InterviewSolutions in .

This section includes InterviewSolutions, each offering curated multiple-choice questions to sharpen your knowledge and support exam preparation. Choose a topic below to get started.

1.

How can you test a generics class?

Answer»

Generics allows creating CLASSES, interfaces or methods that OPERATE with DIFFERENT data types at a time. In order to test Generic entities, we can test it for one or two datatypes for the LOGIC SINCE the datatype allocation are evaluated at compilation time for type-correctness.

2.

How can we do testing for private methods?

Answer»

It is generally not required to test private methods directly. Since they are private, it is assumed that they are called from public methods. If these methods are working as expected, then by extension it is considered that the private methods are working correctly. HOWEVER, we can explore how the private methods are tested using REFLECTION

LET us consider we have a public class Item with private method getItemName() as shown below:

public class Item { private STRING getItemName(String itemName) { //Some logic if(itemName.equals("computer")) { return itemName; } return "laptop"; }}

Consider we have a test class ItemTest that tests this method as shown below:

import static org.junit.Assert.assertEquals;import java.lang.reflect.Method;import org.junit.BeforeClass;import org.junit.Test;public class ItemTest { public static Item item; @BeforeClass public static VOID beforeClass() { item = new Item(); } @Test public void testGetItemNameSuccess() throws Exception { String expectedName = "computer"; Method method = Item.class.getDeclaredMethod("getItemName", String.class); method.setAccessible(true); String actualName = (String) method.invoke(item, actualName); assertEquals(expectedName, actualName); }}

In the above code, we see that we can test the private method by using getDeclaredMethod method of the Method class that belongs to reflection strategy. Since we know that the private methods cant be invoked directly, we can use the Method class object’s invoke() method and send the input parameters. Then as usual, we can compare the results with the expected and the actual methods.

3.

Why does JUnit report only the first failure in a single attempt?

Answer»

JUnit is usually designed in a way that it deals with smaller tests and is capable of RUNNING each ASSESSMENT with a BOUNDARY of separate ANALYSIS. Due to this, it reports only the first failure on each test case attempt.

4.

What are some of the best practices to be followed while writing code for making it more testable?

Answer»

Following are some of the best PRACTICES that can be followed while coding to make the CODE more testable:

  • Make USE of interfaces as a wrapper to IMPLEMENTATION classes. This helps testers to replace the class with mocks or stubs to TEST the module.
  • Use dependency injection wherever needed instead of creating. new objects. This makes it easy for testing individual modules and also supply dependency in the test configuration.
  • Avoid using static methods as that makes it difficult to test because they cannot be called polymorphically.
5.

Is it possible to test the Java method for a timeout in JUnit?

Answer»

Yes, it is possible. @Test annotation provides a timeout parameter that takes value in MILLISECONDS in JUNIT that is USED for INSTRUCTING JUnit to pass or fail the test method based on execution time. For instance, if a test method has Test annotation as @Test(timeout=30), then it means that if the execution does not COMPLETE in 30ms, then the test case will be failed. This helps in verifying the SLA of the Java method.

6.

Define code coverage. What are the different types of code coverages?

Answer»

The extent to which the SOURCE code is UNIT tested is called coverage. There are THREE types of coverage TECHNIQUES, they are:

  • Statement coverage: This ensures that each statement/line in the source code is executed and tested.
  • Decision coverage: This ensures that EVERY decision point that results in true or false is executed and run.
  • Path coverage: This ensures that every possible route from a given point is run and tested.
7.

What is the keyboard shortcut for running the Junit test cases in eclipse IDE?

Answer»

We can PRESS Alt+Shift+X for RUNNING the test. We can also right-click on the PROJECT, select RUN As and then select JUnit Test. If the test METHOD needs to be rerun, then we can press Ctrl+F11.

8.

What is the relationship between the cyclomatic complexity of code and unit tests?

Answer»

The CODE cyclomatic complexity is calculated based on the number of DECISION POINTS of the code that contributes to different execution paths as shown in the image below:

This is why, higher the cyclomatic complexity, the more DIFFICULT is to attain the REQUIRED code coverage.

9.

What are Hamcrest Matchers?

Answer»

Hamcrest is a JUnit framework used to write matcher objects that provides ‘match’ rules DEFINITION in a declarative manner. They are used in UI validation, data filtering and for writing flexible unit TESTS. Hamcrest matches are used in the assertThat() method in JUnit. We can use one or more matchers within this assert method. Some of the matcher methods are as follows:

MatcherDescriptionExample
allOf()This calculates the logical CONJUNCTION of multiple matchers and the object under consideration should match all of the matcher given.assertThat("InterviewBit",allOf(startsWith("In"),containsString(“Bit”)))

--> All conditions should match for assertThat to pass.

anyOf()This is used for calculating the logical disjunction of multiple matchers. This means that the object under consideration matches ANY of the specified matchers.assertThat( "InterviewBit",anyOf(containsString( "Bit" ),containsString( "unit" )));

-->Any of the conditions should match for assertThat to pass.

describedAs()This adds a description to the matcher.assertThat("Friday", describedAs("Friday is not Sunday", is(not("Sunday"))));
is()This decorates another matcher by retaining its behavior. and checks for the equality of the objects. It allows tests to be more EXPRESSIVE and meaningful.assertThat("InterviewBit",is(equalTo("InterviewBit")))
anything()This matcher always returns true.assertThat("InterviewBit",is(anything("foo bar")));
equalTo()This checks for the equality of objects.assertThat("InterviewBit",equalTo("InterviewBit"));
instanceOf()This tests whether the value is an instance of any class.assertThat(instance,instanceOf(InstanceClass.class));
hasItems()This creates matcher for iterables which matches when consecutive passes over Iterable yields at least one item equal to corresponding item from list of items. The iterable STOPS as soon as matching item is found.assertThat(Arrays.asList("Interviewbit", "Junit", "Interview","Questions"), hasItems("Junit", "Questions"))
not()This creates matcher which wraps existing matcher but inverts logic by which it should match.assertThat("InterviewBit", is(not(equalTo("Junit"))));
nullValue()This creates matcher which matches if object that is examined is null.assertThat(obj, is(nullValue()));
10.

What are the differences between @Before, @After, @BeforeClass and @AfterClass?

Answer»

The order of execution of these annotations is as shown below:

@Before@After@BeforeClass@AfterClass
Methods annotated with @Before are executed before each test case.Methods annotated with @After are executed after each test case.Methods annotated with @BeforeClass are executed once before the start of all the test cases.Methods annotated with @AfterClass are executed once all the tests have completed their execution.
This is used for preparing the test environment like to read inputs, INITIALISE the variables etc.This is used for cleaning up the test environment like deleting the temporary data, restoring the value of variables to default. This helps in saving memory.This is used for PERFORMING time-intensive set-up activities like connecting to any resource that is common across all tests. Methods annotated with this API needs to be defined as static methods for WORKING with JUnit.This is used for performing time-intensive cleanup activities like DISCONNECTING from a resource that is common across all tests. Methods annotated with this annotation has to be defined as static methods for it to work with JUnit.
11.

How do you assert exceptions thrown in JUnit 4 tests?

Answer»

Consider an example to see how to write test cases for asserting exceptions.

import org.apache.commons.lang3.StringUtils;PUBLIC final class ExceptionDemo { public String convertToUpperCase(String input) { if (StringUtils.isEmpty(input)) { throw new IllegalArgumentException("Input empty, cannot convert to upper case!!"); } return input.toUpperCase(); }}

The method convertToUpperCase() defined in the ExceptionDemo class would throw an IllegalArgumentException if an empty string is passed as an input to the method.
Let us write unit test cases for asserting the exception thrown in the code. In JUnit, there are 3 different ways of achieving this and they are as follows:

try-catch idiom: We can use the try-catch block for asserting exception as shown below:

@Testpublic void convertToUpperCaseWithTryCatchTest{ try { exceptionDemo.convertToUpperCase(""); fail("It should throw IllegalArgumentException"); } catch (IllegalArgumentException e) { Assertions.assertThat(e) .ISINSTANCEOF(IllegalArgumentException.class) .hasMessage("Input empty, cannot convert to upper case!!"); }}

@Test expected annotation: 

Here we give the expected exception as value to the expected parameter of the @Test annotation as:@Test(expected = IllegalArgumentException.class)

When no exception is thrown by the target method under test, then we will GET the below MESSAGE:

java.lang.AssertionError: Expected exception: java.lang.IllegalArgumentException

Care has to be taken here while defining the expected Exception. We should not expect general Exception, RuntimeException or even a Throwable type of exceptions as that is a bad practice. If we do so, then there are chances that the code can throw an exception in other places and the test case can pass.

Here we cannot assert the message in the exception. The code snippet of the test method would be:

@Test(expected = IllegalArgumentException.class)public void convertToUpperCaseExpectedTest() { exceptionDemo.convertToUpperCase("");}

Junit @Rule:

The same example can be created using the ExceptedException rule. The rule must be a public field marked with @Rule annotation.

@Rulepublic ExpectedException exceptionRule = ExpectedException.none();@Testpublic void convertToUpperCaseRuleTest() { exceptionRule.expect(IllegalArgumentException.class); exceptionRule.expectMessage("Input empty, cannot convert to upper case!!"); exceptionDemo.convertToUpperCase("");}

 In this approach, when the exception is not thrown, we will get:

java.lang.AssertionError: Expected test to throw (an instance of java.lang.IllegalArgumentException and exception with the message “Input empty, cannot convert to upper case!!”)
12.

How can we run JUnit from the command window?

Answer»

The FIRST step is to SET the CLASSPATH with the library PATH. Then invoke the JUnit runner by running the command:

java org.junit.runner.JUnitCore

To run the test class VIA commandline, we would first have to compile the class. This can be done by running:

javac -d target -cp target:junit-platform-console-standalone-1.7.2.jar src/test/java/com/pathTo/DemoTest.java

Then we can run the compiled test class using the console launcher of JUnit by running the following command:

java -jar junit-platform-console-standalone-1.7.2.jar --class-path target --select-class com.pathTo.DemoTest
13.

Why can't we use System.out.println() for testing and debugging?

Answer»

If we use System.out.println() for DEBUGGING, then we would have to do a manual SCAN of the outputs every time program is executed to ensure that the output PRINTED is the expected output. Also, in the longer run, writing JUnit tests will be easier and will take lesser time. Writing test cases will be like an initial investment and then, LATER on, we can later AUTOMATICALLY test them on the classes.

14.

How can we test protected methods?

Answer»

For testing PROTECTED methods, the test CLASS should be DECLARED in the same package as that of the target class.

15.

What is the purpose of @Before and @After annotations in JUnit 4?

Answer»

These are the annotations PRESENT in JUNIT 4. Methods annotated with @Before will be called and RUN before the execution of each test case. Methods annotated with @After will be called and executed after the execution of each test case. If we have 5 test cases in a JUnit CLASS, then the methods annotated with these two would be run 5 times. In JUnit 5, the annotations @Before and @After are renamed to @BeforeEach and @AfterEach for making it more readable.

16.

How to ignore tests in JUnit?

Answer»

We NEED to IGNORE test cases when we have certain functionalities that are not certain or they are under development. To wait for the completion of the code, we can AVOID running these test cases. In JUnit 4, we can achieve this by using @Ignore annotation over the test methods. In JUnit 5, we can do it using @DISABLED annotation over the test methods.

17.

What are the differences between JUnit and TestNG?

Answer»
JUnitTestNG
Open-source unit TESTING framework for writing test cases.TestNG is similar to JUnit but with extended functionalities.
JUnit does not support advanced annotations.This supports advanced and special annotations too.
JUnit does not support PARALLEL testing.TestNG supports MULTIPLE threads to run parallelly.
Group test is not supported.TestNG is supported in TestNG.
The naming CONVENTION for annotations like Before, After, Expected are confusing.The naming convention for understanding annotations like BeforeMethod, AfterMethod, ExpectedException is easy to understand based on their functionality.
Cannot rerun FAILED cases.Can rerun failed tests.
18.

What are the differences between JUnit 4 and JUnit 5?

Answer»
CategoryJUNIT 4JUnit 5
Annotation for executing method before all test methods run in the current class@BeforeClass@BeforeAll
Annotation for executing method after all test methods run in the current class@AfterClass@AfterAll
Annotation for executing method before each test case@Before@BeforeEach
Annotation for executing method after each test method@After@AfterEach
ArchitectureIt has everything like PLATFORM, annotations etc bundled in a single jar file.JUnit 5 is composed of 3 sub-units - JUnit Platform, JUnit Jupiter and JUnit Vintage
Required JDK VersionThis needs Java 5 or higher versions.This needs Java 8 or above.
AssertionsAssert methods are present in org.junit.Assert package for validating expected and actual outputs.Assert methods are present in the org.junit.jupiter.Assertions package. The methods also have overloaded methods for SUPPORTING error messages in case TESTS FAIL.
19.

What are the best practices for writing Unit Test Cases?

Answer»

A standard unit test case comprises a known INPUT and an expected output. These two things need to be known before we run the test case. A known input is tested for a precondition and an expected output is tested by postcondition. Following are the best practices for writing unit test cases:

  • For every method, we need to have at least two unit test cases - a positive test case and a negative test case.
  • If there are sub-requirements for a requirement, then those sub-requirements should have their own positive and negative test cases.
  • Each test case should be independent of other test cases. If we make a CHAIN of unit test cases, then it would not be possible for FINDING the root cause of the test case failures.
  • Mock all the external services that are used by the modules under test. This is necessary because we do not want to unnecessarily debug our modules under test due to the failures of the external systems.
  • Configuration settings need not be tested as they won’t be part of any unit code. Even if we want to inspect the configuration, then test WHETHER the loading code is working or not.
  • The unit test cases should be named consistently and clearly. The names of the test cases should be dependent on the OPERATIONS that the test case would test.