UTBotJava icon indicating copy to clipboard operation
UTBotJava copied to clipboard

Fuzzer ignores generics of `class StringMap extends HashMap<String, String>`

Open IlyaMuravjov opened this issue 2 years ago • 4 comments

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();
}

IlyaMuravjov avatar Aug 31 '23 10:08 IlyaMuravjov

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.

alisevych avatar Sep 20 '23 16:09 alisevych

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.

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.

IlyaMuravjov avatar Sep 20 '23 22:09 IlyaMuravjov

@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 avatar Sep 25 '23 11:09 alisevych

@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?

Markoutte avatar Sep 25 '23 11:09 Markoutte