Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve mock type inference in fuzzer #2536

Merged
merged 5 commits into from
Aug 22, 2023

Conversation

IlyaMuravjov
Copy link
Collaborator

@IlyaMuravjov IlyaMuravjov commented Aug 21, 2023

Description

Substitute actual types from receiver type in place of type variables in mocks created by MockValueProvider.

For example, if stringOptional has type Optional<String>, then stringOptional.get() return value of type String.

How to test

Manual tests

  1. Generate unit tests for OwnerService.getOrderById() method from spring-boot-testing project. There should be test like the one bellow and no tests for ClassCastException.
@Test
@DisplayName("getOrderById: id = -9223372036854775807 (mutated from positive)")
public void testGetOrderById() throws Throwable {
    Optional optionalMock1 = mock(Optional.class);
    Order orderMock1 = mock(Order.class);
    (when(optionalMock1.orElseThrow(any()))).thenReturn(orderMock1);
    (when(orderRepositoryMock.findById(any()))).thenReturn(optionalMock1);

    Order actual = simpleOrderService.getOrderById(-9223372036854775807L);

    assertSame(orderMock1, actual);

    Long actualId = ((Long) getFieldValue(actual, "com.rest.order.models.Order", "id"));
    assertNull(actualId);

    String actualBuyer = ((String) getFieldValue(actual, "com.rest.order.models.Order", "buyer"));
    assertNull(actualBuyer);

    Double actualPrice = ((Double) getFieldValue(actual, "com.rest.order.models.Order", "price"));
    assertNull(actualPrice);

    int orderMock1Qty = ((Integer) getFieldValue(orderMock1, "com.rest.order.models.Order", "qty"));
    int actualQty = ((Integer) getFieldValue(actual, "com.rest.order.models.Order", "qty"));
    assertEquals(orderMock1Qty, actualQty);

}
  1. Generate tests for methods that work with more complex receiver generic types, types should still be inferred correctly. Here's an example of such method:
public String getFirst(Optional<? extends List<? extends String>> optional) {
    return optional.get().get(0);
}

Limitations

Generics are only inferred when they are declared at the class level, meaning that for methods that are themselves parametrized (e.g. <R> Stream<R> map(Function<? super T, ? extends R> mapper)) types are not inferred.

Self-check list

  • I've set the proper labels for my PR (at least, for category and component).
  • PR title and description are clear and intelligible.
  • I've added enough comments to my code, particularly in hard-to-understand areas.
  • The functionality I've repaired, changed or added is covered with automated tests.
  • Manual tests have been provided optionally.
  • The documentation for the functionality I've been working on is up-to-date.

@IlyaMuravjov IlyaMuravjov added comp-fuzzing Issue is related to the fuzzing ctg-enhancement New feature, improvement or change request comp-spring Issue is related to Spring projects support labels Aug 21, 2023
@IlyaMuravjov IlyaMuravjov marked this pull request as ready for review August 21, 2023 12:23
@EgorkaKulikov EgorkaKulikov enabled auto-merge (squash) August 22, 2023 14:47
@EgorkaKulikov EgorkaKulikov merged commit ace9742 into main Aug 22, 2023
@EgorkaKulikov EgorkaKulikov deleted the ilya_m/infer_fuzzed_mock_types branch August 22, 2023 15:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
comp-fuzzing Issue is related to the fuzzing comp-spring Issue is related to Spring projects support ctg-enhancement New feature, improvement or change request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants