Skip to content

Disable NPE checks for non-public library fields #358

Closed
@Damtev

Description

@Damtev

Description

For now, the engine considers method invocations or field access on null values as producing NullPointerException. Previously in #226 such NPE checks were disabled for final fields from library classes because it often leads to the generation of tests with exceptions that are unexpected for a user with high usage of Java reflection. It is suggested to extend such a strategy to non-public fields from library classes too, for the same reasons.

Expected behavior

Consider generating tests for such a method:

public class DateExample {
    boolean foo(Date date) {
        return date.getTime() == 100;
    }
}

Only such 3 tests are expected by user:

@Test
@DisplayName("foo: return date.getTime() == 100 : False -> return date.getTime() == 100")
public void testFoo_DateGetTimeNotEquals100() {
    DateExample dateExample = new DateExample();
    Date date = new Date(-155L);

    boolean actual = dateExample.foo(date);

    assertFalse(actual);
}

@Test
@DisplayName("foo: return date.getTime() == 100 : True -> return date.getTime() == 100")
public void testFoo_DateGetTimeEquals100() {
    DateExample dateExample = new DateExample();
    Date date = new Date(100L);

    boolean actual = dateExample.foo(date);

    assertTrue(actual);
}

@Test
@DisplayName("foo: return date.getTime() == 100 : True -> ThrowNullPointerException")
public void testFoo_DateGetTime() {
    DateExample dateExample = new DateExample();

    assertThrows(NullPointerException.class, () -> dateExample.foo(null));
}

But for now, UtBot also generates at least 2 such tests:

@Test
@DisplayName("foo: return date.getTime() == 100 : True -> ThrowNullPointerException")
public void testFoo_ThrowNullPointerException() throws Exception {
    DateExample dateExample = new DateExample();
    Date date = ((Date) createInstance("java.util.Date"));
    Object immutableGregorianDate = createInstance("sun.util.calendar.ImmutableGregorianDate");
    setField(immutableGregorianDate, "date", null);
    setField(date, "cdate", immutableGregorianDate);

    assertThrows(NullPointerException.class, () -> dateExample.foo(date));
}

@Test
@DisplayName("foo: return date.getTime() == 100 : True -> ThrowNullPointerException")
public void testFoo_ThrowNullPointerException_1() throws ClassNotFoundException, Exception {
    Class dateClazz = Class.forName("java.util.Date");
    BaseCalendar prevGcal = ((BaseCalendar) getStaticFieldValue(dateClazz, "gcal"));
    BaseCalendar prevJcal = ((BaseCalendar) getStaticFieldValue(dateClazz, "jcal"));
    try {
        setStaticField(dateClazz, "gcal", null);
        setStaticField(dateClazz, "jcal", null);
        DateExample dateExample = new DateExample();
        Date date = ((Date) createInstance("java.util.Date"));
        Object immutableGregorianDate = createInstance("sun.util.calendar.ImmutableGregorianDate");
        LocalGregorianCalendar.Date date1 = ((LocalGregorianCalendar.Date) createInstance("sun.util.calendar.LocalGregorianCalendar$Date"));
        setField(date1, "zoneinfo", null);
        setField(date1, "normalized", false);
        setField(date1, "millis", 0);
        setField(date1, "seconds", 0);
        setField(date1, "minutes", 0);
        setField(date1, "hours", 0);
        setField(date1, "dayOfMonth", 0);
        setField(date1, "month", 0);
        setField(date1, "gregorianYear", 11564545);
        setField(immutableGregorianDate, "date", date1);
        setField(date, "cdate", immutableGregorianDate);

        dateExample.foo(date);
    } finally {
        setStaticField(Date.class, "gcal", prevGcal);
        setStaticField(Date.class, "jcal", prevJcal);
    }
}

These tests SHOULD NOT be generated (in the plugin, at least).

Environment

No mocks, Java.

Potential alternatives

Unknown.

Context

We can possibly lose some branches with such disabling.

Metadata

Metadata

Assignees

Labels

comp-symbolic-engineIssue is related to the symbolic execution engine

Type

No type

Projects

Status

Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions