I wrote test cases for below class but problem is still its not getting covered 100% and i mentioned not coverage code with > symbol in my below class can some one suggest me what can i do for cover remaining code
Repository class
public RowMapperServerResponse insertproductDetails(RowMapperServerResponse rowMapperServerResponse) {
try {
int insertRow = jdbcTemplate.update(
"insert into Master_Circuit (id_type,product,seq_no,name,dependent_count,create_time) values(?,?,?,?,?,?)",
rowMapperServerResponse.getId_type(), rowMapperServerResponse.getProduct(),
rowMapperServerResponse.getSeq_no(), rowMapperServerResponse.getName(),
rowMapperServerResponse.getDependent_count(), rowMapperServerResponse.getCreate_time());
*
> if (insertRow != 0) {
> return rowMapperServerResponse;
> }
> } catch (EmptyResultDataAccessException e) {
> return null;
> }
*
return null;
}
test cases
#Test
public void insertproductDetailsTest() {
baaisnEvcIdMSRepository.insertproductDetails(rowResponse());
Mockito.when(jdbcTemplate.update(Mockito.anyString(), Mockito.anyString(), Mockito.anyString(),
Mockito.anyInt(), Mockito.anyString(), Mockito.anyInt(), Mockito.any())).thenReturn(1);
Mockito.verify(jdbcTemplate, Mockito.times(1)).update(Mockito.anyString(), Mockito.anyString(),
Mockito.anyString(), Mockito.anyInt(), Mockito.anyString(), Mockito.anyInt(), Mockito.any());
}
#Test
public void insertproductDetailsEmptyTest() {
baaisnEvcIdMSRepository.insertproductDetails(rowResponse());
Mockito.when(jdbcTemplate.update(Mockito.anyString(), Mockito.anyString(), Mockito.anyString(),
Mockito.anyInt(), Mockito.anyString(), Mockito.anyInt(), Mockito.any())).thenReturn(0);
Mockito.verify(jdbcTemplate, Mockito.times(1)).update(Mockito.anyString(), Mockito.anyString(),
Mockito.anyString(), Mockito.anyInt(), Mockito.anyString(), Mockito.anyInt(), Mockito.any());
}
private RowMapperServerResponse rowResponse() {
RowMapperServerResponse rowMapperServerResponse = mock(RowMapperServerResponse.class);
Mockito.when(rowMapperServerResponse.getMaster_kit_id()).thenReturn(464662);
Mockito.when(rowMapperServerResponse.getId_type()).thenReturn("EMSsample");
Mockito.when(rowMapperServerResponse.getProduct()).thenReturn("sample");
Mockito.when(rowMapperServerResponse.getSeq_no()).thenReturn(36316);
Mockito.when(rowMapperServerResponse.getName()).thenReturn("TLS");
Mockito.when(rowMapperServerResponse.getDependent_count()).thenReturn(0);
Mockito.when(rowMapperServerResponse.getCreate_time()).thenReturn(new Date());
return rowMapperServerResponse;
}
I suggest just putting a breakpoint inside the if block.
If there code is not covered, obviously no test enters that block.
One possible issue would be that you call the baaisnEvcIdMSRepository.insertproductDetails and only afterthat (next line in the test) specify the expectations in Mockito. I'm not a mockito expert, but during the "Subject Under Test" execution how Mockito can know that you expect it to return 0 / 1? If it uses some defaults, it can always return 0, so if branch won't be executed.
Related
This question already has answers here:
Interrupt test class at the first test failure
(3 answers)
Closed 1 year ago.
I have to write a test divided into several steps. Each step is based on the previous one so if one fails, testing should be stopped.
#TestMethodOrder(AlphanumericOrder.class)
public class TestCase {
#Test
public void step10() {
Assertions.assertTrue(true);
}
#Test
public void step20() {
Assertions.assertTrue(false);
}
#Test
public void step30() {
Assertions.assertTrue(true);
}
#Test
public void step40() {
Assertions.assertTrue(true);
}
}
In the example above testing should be terminated after step20(). I implemented custom MethodOrder to ensure correct sequence of execution. The problem I have is how to stop other tests after one fails? I tried to implement TestWatcher with no success. Is there any built-in mechanism in JUnit5 that can solve my problem?
Working solution that was shared in the comments:
Reference: Interrupt test class at the first test failure
#ExtendWith(StepwiseExtension.class)
#TestMethodOrder(AlphanumericOrder.class)
public class TestCase {
#Test
public void step10() {
Assertions.assertTrue(true);
}
#Test
public void step20() {
Assertions.assertTrue(false);
}
#Test
public void step30() {
Assertions.assertTrue(true);
}
#Test
public void step40() {
Assertions.assertTrue(true);
}
#BeforeEach
public void before(){
}
}
class StepwiseExtension implements ExecutionCondition, TestExecutionExceptionHandler {
#Override
public ConditionEvaluationResult evaluateExecutionCondition(ExtensionContext extensionContext) {
ExtensionContext.Namespace namespace = namespaceFor(extensionContext);
ExtensionContext.Store store = storeFor(extensionContext, namespace);
String value = store.get(StepwiseExtension.class, String.class);
return value == null ? ConditionEvaluationResult.enabled("No test failures in stepwise tests") :
ConditionEvaluationResult.disabled(String.format("Stepwise test disabled due to previous failure in '%s'", value));
}
#Override
public void handleTestExecutionException(ExtensionContext extensionContext, Throwable throwable) throws Throwable {
ExtensionContext.Namespace namespace = namespaceFor(extensionContext);
ExtensionContext.Store store = storeFor(extensionContext, namespace);
store.put(StepwiseExtension.class, extensionContext.getDisplayName());
throw throwable;
}
private ExtensionContext.Namespace namespaceFor(ExtensionContext extensionContext){
return ExtensionContext.Namespace.create(StepwiseExtension.class, extensionContext.getParent());
}
private ExtensionContext.Store storeFor(ExtensionContext extensionContext, ExtensionContext.Namespace namespace){
return extensionContext.getParent().get().getStore(namespace);
}
}
I have a test scenario where I need to mock a Consumer parameter.
In the following code the startTracer is the method to be tested.
class TracerService {
private TracerController tracerController;
public void startTracer(String tracerName, Object param1) {
if (attendStartConditions(tracerName, param1)) {
executeOnTracerControllerScope(tracerController -> tracerController.startTracer(param1));
}
}
...
}
Basically, I want to test if the tracerController.startTracer(param1) is receiving the param1 as argument.
Capture<Object> method1Param1 = newCapture();
tracerController.startTracer(capture(method1Param1));
expectLastCall().once();
...
tracerService.startTracer("TEST", "value1");
assertThat(method1Param1.getValue()).isEqualsTo("value1");
How I can configure EasyMock/PowerMock for that executeOnTracerControllerScope execute tracerController.startTracer without invocating their internal code?
tracerController is a mock. So startTracer won't be called on it. As defined right now, it will simply do nothing. The code doing what you are asking should be something like that:
Capture<Object> method1Param1 = newCapture();
tracerController.startTracer(capture(method1Param1)); // no need for the expect, it's the default
replay(tracerController);
// ...
tracerService.startTracer("TEST", "value1");
assertThat(method1Param1.getValue()).isEqualsTo("value1");
Of course, attendStartConditions and executeOnTracerControllerScope will be called for real.
Following your comment, if you want to mock executeOnTracerControllerScope, you will do the code below. However, your lambda won't be called anymore. So you won't be able to validate the param.
public class MyTest {
#Test
public void test() {
TracerController tracerController = mock(TracerController.class);
TracerService service = partialMockBuilder(TracerService.class)
.withConstructor(tracerController)
.addMockedMethod("executeOnTracerControllerScope")
.mock();
replay(tracerController);
service.startTracer("tracer", "param");
}
}
class TracerService {
private final TracerController tracerController;
public TracerService(TracerController tracerController) {
this.tracerController = tracerController;
}
public boolean attendStartConditions(String tracerName, Object param1) {
return true;
}
public void executeOnTracerControllerScope(Consumer<TracerController> tracer) {
tracer.accept(tracerController);
}
public void startTracer(String tracerName, Object param1) {
if (attendStartConditions(tracerName, param1)) {
executeOnTracerControllerScope(tracerController -> tracerController.startTracer(param1));
}
}
}
interface TracerController {
void startTracer(Object param1);
}
I have a class with many functions
public class Test {
public void a() {
try {
doSomething1();
} catch (AException e) {
throw new BException(e.getMessage(), e.getCause());
}
}
public void b() {
try {
doSomething2();
} catch (AException e) {
throw new BException(e.getMessage(), e.getCause());
}
}
}
In each method, an exception of certain type is caught and converted to another exception and thrown.
I want to remove duplication.
You may remove duplication using lambda:
The CallableEx takes any exception, in case you are working with checked exception. You would not need it if AException was an unchecked exception. Callable interface won't help you much because it throws an Exception and not your AException: you would have to check for instance and so on.
You could probably write the body instead of this::doSomething1, but I advise against it: this makes the code clearer and it separates concerns.
You could probably also use an annotation processor to do the same job and to rewrite the method in order to wrap your AException into a BException. You would not have duplication in your Java code, but your bytecode certainly will.
Here the example with lambda:
public class Test {
#FunctionalInterface
interface CallableEx<T, E extends Exception> {
T run() throws E;
}
private <T> void handleException(CallableEx<T, AException> forrestGump) {
try {
return forrestGump.run();
} catch (AException e) {
throw new BException(e.getMessage(), e.getCause());
}
}
public String a() {
return handleException(this::doSomething1);
}
public int b(int a, int b) {
return handleException(() -> this.doSomething2(a, b));
}
public <T extends Foobar> void c(T my) {
handleException(() -> this.doSomething3(my));
}
private String doSomething1() {return "A";}
private int doSomething2(int a, int b) {return a + b;}
private <T extends Foobar> void doSomething3(T my) {my.foo();}
}
I have the following code in java.
if( response != null && response.getResponseBlock() != null)
{
//do something
}
How can I cover 100% Branch coverage of the condition in the if ().
Even though the condition is a valid java statement, I can never achieve the case when getResponseBlock is not null but response is null.
Please advise.
We will need to cover all test possibilities for if. In this case, we may have four possibilities.
For example the class:
package com.java.basics;
public class Response {
private String responseBlock;
public static void main(String[] args) {
Response response = new Response();
if (response != null && response.getResponseBlock() != null) {
// something
}
}
public String getResponseBlock() {
return responseBlock;
}
public void setResponseBlock(String responseBlock) {
this.responseBlock = responseBlock;
}
}
Can be tested...
package com.java.basics.test;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import org.junit.Before;
import org.junit.Test;
public class ResponseTest {
private Response response;
#Before
public void setUp() throws Exception {
response = new Response();
response.setResponseBlock("Test");
}
#Test
public void testIsResponseIsNull() {
//25 %
response = null;
assertNull(response);
}
#Test
public void testIsResponseIsNotNull() {
//25 %
assertNotNull(response);
}
#Test
public void testIsResponseBlockIsNull() {
//25 %
response.setResponseBlock(null);
assertNull(response.getResponseBlock());
}
#Test
public void testIsResponseBlockIsNotNull() {
//25 %
assertNotNull(response.getResponseBlock());
}
}
I feel the answer is as the comment :
Is it a state which is prevented by a Java Language Specification itself? I liked the words of Uncle Bob here: blog.cleancoder.com/uncle-bob/2017/03/06/TestingLikeTheTSA.html Treat 100% [coverage] as an asymptotic goal. – eug.nikolaev
Since java does not allow it, we cannot cover it 100%. 100% junit coverage for branch and line is an idealistic aim, which should be tried for whenever possible. But sometimes, when its not possible, its not possible. Accept it and move on to solve better problems.
I have this test:
#Test
public void shouldReturn2Hours() {
Float expectedHours = 2f;
WorkChronometer workChronometer = Mockito.mock(WorkChronometer.class);
Mockito.when(workChronometer.getAccumulatedMinutes()).thenReturn(120);
Assert.assertEquals(expectedHours, workChronometer.getAccumulatedHours());
}
and the implementation of WorkChronometer:
public class WorkChronometer {
private DateTime startingInstant;
private DateTime stoppingInstant;
private Boolean counting;
//More methods
public Integer getAccumulatedMinutes() {
if (counting)
throw new RuntimeException("Call stopCount first!");
if (startingInstant == null || stoppingInstant == null)
return 0;
return Minutes.minutesBetween(startingInstant, stoppingInstant).getMinutes();
}
public Float getAccumulatedHours() {
Integer accumulatedMinutes = getAccumulatedMinutes();
return accumulatedMinutes / 60f;
}
}
When I execute the test, it fails:
junit.framework.AssertionFailedError: expected:<2.0> but was:<0.0>
But I don't know why. It seems the mock is not returning what I want.
What am I doing wrong?
Thanks.
You're mocking the class under test. Doing that relaces all the methods by methods doing nothing, and returning default values.
If you want to do that, you'll need a spy, or a partial mock.
With a spy:
#Test
public void shouldReturn2Hours() {
Float expectedHours = 2f;
WorkChronometer workChronometer = new WorkChronometer();
WorkChronometer spy = Mockito.spy(workChronometer);
doReturn(120).when(spy).getAccumulatedMinutes();
Assert.assertEquals(expectedHours, spy.getAccumulatedHours());
}
With a partial mock:
#Test
public void shouldReturn2Hours() {
Float expectedHours = 2f;
WorkChronometer workChronometer = Mockito.mock(WorkChronometer.class);
Mockito.when(workChronometer.getAccumulatedHours()).thenCallRealMethod();
Mockito.when(workChronometer.getAccumulatedMinutes()).thenReturn(120);
Assert.assertEquals(expectedHours, workChronometer.getAccumulatedHours());
}