Closed tushar886 closed 1 month ago
Tried to reproduce the issue using this class:
package org.unlogged.demo.service;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class SimpleService {
private List<String> dataList;
private String importantString;
private int importantNumber;
private double importantDouble;
private Map<Integer, String> importantMap;
public SimpleService(Map<Integer, String> importantMap) {
this.dataList = new ArrayList<>();
this.importantString = "";
this.importantNumber = 0;
this.importantDouble = 0.0;
this.importantMap = importantMap;
}
public List<String> processData() {
dataList = new ArrayList<>();
dataList.add("TestString");
importantDouble = 5.5;
importantNumber = (int) Math.round(importantDouble);
importantString = "hello";
for (int i = 0; i < importantNumber; i++) {
dataList.add(importantString + i);
importantMap.put(i,importantString + i);
}
return dataList;
}
}
The generated test case looks like:
package org.unlogged.demo.service;
import static io.unlogged.UnloggedTestUtils.*;
import static org.mockito.ArgumentMatchers.*;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.lang.Double;
import java.lang.Exception;
import java.lang.String;
import java.util.List;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
public final class TestSimpleServiceV {
private SimpleService simpleService;
private J jVar;
private Double doubleValueVar;
private ObjectMapper objectMapper = new ObjectMapper();
@Before
public void setup() throws Exception {
simpleService = new SimpleService();
jVar = new J();
doubleValueVar = new Double();
injectField(simpleService, "jVar", jVar);
injectField(simpleService, "doubleValueVar", doubleValueVar);
}
@Test
public void processData() throws Exception {
// Test candidate method [processData] [451,1] - took 3ms
List<String> list = simpleService.processData();
List listExpected = objectMapper.readValue("[\"TestString\",\"hello0\",\"hello1\",\"hello2\",\"hello3\",\"hello4\",\"hello5\"]", List.class);
Assert.assertEquals(listExpected, list);
}
}
Multiple Issues are visible:
All these need to be fixed in Test generation.
Class used:
package org.unlogged.demo.controller;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class SampleService {
private List<String> dataList;
private String importantString;
private int importantNumber;
private double importantDouble;
private Map<Integer, String> importantMap;
public SampleService(Map<Integer, String> importantMap) {
this.dataList = new ArrayList<>();
this.importantString = "";
this.importantNumber = 0;
this.importantDouble = 0.0;
this.importantMap = importantMap;
}
public List<String> processData() {
dataList = new ArrayList<>();
dataList.add("TestString");
importantDouble = 5.5;
importantNumber = (int) Math.round(importantDouble);
importantString = "hello";
for (int i = 0; i < importantNumber; i++) {
dataList.add(importantString + i);
importantMap.put(i,importantString + i);
}
return dataList;
}
}
The final test case generated:
package org.unlogged.demo.controller;
import static io.unlogged.UnloggedTestUtils.*;
import static org.mockito.ArgumentMatchers.*;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.lang.Exception;
import java.lang.Integer;
import java.lang.String;
import java.util.HashMap;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
public final class TestSampleServiceV {
private SampleService sampleService;
private HashMap<Integer, String> importantMap;
private ObjectMapper objectMapper = new ObjectMapper();
@BeforeEach
public void setup() throws Exception {
importantMap = new HashMap();
sampleService = new SampleService(importantMap);
}
@Test
public void testMethodProcessData() throws Exception {
// Test candidate method [processData] [483,1] - took 1ms
List<String> list = sampleService.processData();
List listExpected = objectMapper.readValue("[\"TestString\",\"hello0\",\"hello1\",\"hello2\",\"hello3\",\"hello4\",\"hello5\"]", List.class);
Assertions.assertEquals(listExpected, list);
}
}
Replacing the single argument constructor with:
public SampleService(List<String> dataList, String importantString, int importantNumber, double importantDouble, Map<Integer, String> importantMap) {
this.dataList = dataList;
this.importantString = importantString;
this.importantNumber = importantNumber;
this.importantDouble = importantDouble;
this.importantMap = importantMap;
}
The final test case generated is:
package org.unlogged.demo.controller;
import static io.unlogged.UnloggedTestUtils.*;
import static org.mockito.ArgumentMatchers.*;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.lang.Exception;
import java.lang.Integer;
import java.lang.String;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
public final class TestSampleServiceV {
private SampleService sampleService;
private ArrayList<String> dataList;
private HashMap<Integer, String> importantMap;
private ObjectMapper objectMapper = new ObjectMapper();
@BeforeEach
public void setup() throws Exception {
importantMap = new HashMap();
dataList = new ArrayList();
String importantString = "";
sampleService = new SampleService(dataList, importantString, 0, 0, importantMap);
}
@Test
public void testMethodProcessData() throws Exception {
// Test candidate method [processData] [455,1] - took 2ms
List<String> list = sampleService.processData();
List listExpected = objectMapper.readValue("[\"TestString\",\"hello0\",\"hello1\",\"hello2\",\"hello3\",\"hello4\",\"hello5\"]", List.class);
Assertions.assertEquals(listExpected, list);
}
}
Here an improvement could be to initialize double with 0.0 and not just 0 for clarity in the test case.
Describe the bug
For the cases where the method is not having any arguments and using class level arguments only. COnsider the case of struts where the ACtion class code is like this 👍
`File Name : Employee.java
@Authorized(action = "commonData", permission = "read") public void getEmpDetailDataList() throws Exception { try { if (employeeIdList == null) employeeIdList = new ArrayList<>();
Here we can see that method in itself does not have any arguments rather its using all class level arguments.
When test generation of such a method is happening there all variables are not getting mocked but rather few are skipped.
Mocked generated test of such example
`
public final class TestEmployeeV {
Here we can see the fields like employeeDataList and date are missing from test case generated
Reproduction steps
Expected behavior
All related variables within scope of that method should be mocked and generated
Additional context
No response