Fuzzer ignores generics of `class StringMap extends HashMap<String, String>`
Description
Fuzzer tries to put arbitrary Objects into StringMap
To Reproduce
- Set fuzzing to
100% - Generate tests for the following class
public class StringMap extends HashMap<String, String> {
public String getAnyString() {
return keySet().iterator().next();
}
}
Expected behavior
There's one passing and one failing test.
Actual behavior
No passing tests are generated, one of the tests fails to compile with the following error: "incompatible types: Object cannot be converted to String stringMap.put(object, object1);".
Visual proofs (screenshots, logs, images)
/**
* @utbot.classUnderTest {@link StringMap}
* @utbot.methodUnderTest {@link StringMap#getAnyString()}
*/
@Test
@DisplayName("getAnyString: -> throw ClassCastException")
public void testGetAnyStringThrowsCCE() {
StringMap stringMap = new StringMap();
Object object = new Object();
Object object1 = new Object();
stringMap.put(object, object1);
/* This test fails because method [org.example.StringMap.getAnyString] produces [java.lang.ClassCastException: class java.lang.Object cannot be cast to class java.lang.String (java.lang.Object and java.lang.String are in module java.base of loader 'bootstrap')]
org.example.StringMap.getAnyString(StringMap.java:7) */
stringMap.getAnyString();
}
A very similar issue is reproducing on spring-petclinic project with PetController tests.
Is it the same?
Tests are not compiling.
ModelMap is spring framework type extending LinkedHashMap<String, Object> Fuzzer is generating Objects as keys to fill it.
///region FUZZER: TIMEOUTS for method initCreationForm(org.springframework.samples.petclinic.owner.Owner, org.springframework.ui.ModelMap)
/**
* @utbot.classUnderTest {@link PetController}
* @utbot.methodUnderTest {@link PetController#initCreationForm(Owner, ModelMap)}
*/
@Test
@DisplayName("initCreationForm: owner = mock(), model = collection")
@Timeout(value = 1000L, unit = TimeUnit.MILLISECONDS)
public void testInitCreationForm1() {
Owner ownerMock = mock(Owner.class);
(((Owner) (doNothing()).when(ownerMock))).addPet(any());
ModelMap model = new ModelMap();
Object object = new Object();
Object object1 = new Object();
model.put(object, object1);
Object object2 = new Object();
Object object3 = new Object();
model.put(object2, object3);
Object object4 = new Object();
Object object5 = new Object();
model.put(object4, object5);
Object object6 = new Object();
Object object7 = new Object();
model.put(object6, object7);
/* This execution may take longer than the 1000 ms timeout
and therefore fail due to exceeding the timeout. */
assertTimeoutPreemptively(Duration.ofMillis(1000L), () -> petController.initCreationForm(ownerMock, model));
}
And issue - #2595 - is present too.
A very similar issue is reproducing on
spring-petclinicproject with PetController tests. Is it the same? Tests are not compiling.ModelMap is spring framework type extending LinkedHashMap<String, Object> Fuzzer is generating Objects as keys to fill it.
///region FUZZER: TIMEOUTS for method initCreationForm(org.springframework.samples.petclinic.owner.Owner, org.springframework.ui.ModelMap) /** * @utbot.classUnderTest {@link PetController} * @utbot.methodUnderTest {@link PetController#initCreationForm(Owner, ModelMap)} */ @Test @DisplayName("initCreationForm: owner = mock(), model = collection") @Timeout(value = 1000L, unit = TimeUnit.MILLISECONDS) public void testInitCreationForm1() { Owner ownerMock = mock(Owner.class); (((Owner) (doNothing()).when(ownerMock))).addPet(any()); ModelMap model = new ModelMap(); Object object = new Object(); Object object1 = new Object(); model.put(object, object1); Object object2 = new Object(); Object object3 = new Object(); model.put(object2, object3); Object object4 = new Object(); Object object5 = new Object(); model.put(object4, object5); Object object6 = new Object(); Object object7 = new Object(); model.put(object6, object7); /* This execution may take longer than the 1000 ms timeout and therefore fail due to exceeding the timeout. */ assertTimeoutPreemptively(Duration.ofMillis(1000L), () -> petController.initCreationForm(ownerMock, model)); }And issue - #2595 - is present too.
Yes, it's the same issue.
#2595 only reproduces on UtBot version from #2583 and I hope it will be fixed before #2583 is merged.
@Markoutte The issue is reproducing with the PR merged. I've taken IU plugin from here: https://github.com/UnitTestBot/UTBotJava/actions/runs/6257133258
The following test is generated for spring-petclinic PetController class processCreationForm method:
@Test
public void testProcessCreationFormByFuzzer4() {
Owner ownerMock = mock(Owner.class);
(((Owner) (doNothing()).when(ownerMock))).addPet(any());
Pet petMock = mock(Pet.class);
(when(petMock.getName())).thenReturn("");
BindingResult resultMock = mock(BindingResult.class);
(when(resultMock.hasErrors())).thenReturn(true);
ModelMap model = new ModelMap();
Object object = new Object();
model.put(((Object) "\n\t\r"), object);
String actual = petController.processCreationForm(ownerMock, petMock, resultMock, model);
String expected = "pets/createOrUpdatePetForm";
assertEquals(expected, actual);
}
model.put... is not compiling
Can you please check?
@alisevych Looks like the problem here:
model.put(((Object) "\n\t\r"), object);
Most likely, it won't compile because of an error with code gen part that try to cast String to Object before it puts the string into map. I've wrote about this problem in PR: #2610. Maybe @EgorkaKulikov or @IlyaMuravjov could take a look at this problem?