Skip to content

Issue with statics in parametrized test generation #612

Closed
@sofurihafe

Description

@sofurihafe

Description

When generating parametrized tests, data provider doesn't change static field of a class that will be tested later and is expected to be changed beforehand, which causes some tests to fail.

To Reproduce

  1. Enable parametrized test generation for samples,
  2. Run StaticsSubstitutionTest, NotNullAnnotationTest, UnsafeWithFieldTest

Actual behavior

StaticsSubstitutionTest:

Generated not parametrized test looks like this:

public class StaticSubstitutionExamplesGeneratedTest {
    ///region Test suites for executable org.utbot.examples.statics.substitution.StaticSubstitutionExamples.lessThanZero
    
    ///region
    
    /**
    <pre>
    Test executes conditions:
 *     {@code (value > 0): False }
 * returns from: {@code return value > 0 ? value : 0; }
 * </pre>
     */
    @Test
    @DisplayName("lessThanZero: value > 0 : False -> return value > 0 ? value : 0")
    public void testLessThanZero_ValueLessOrEqualZero() {
        int prevMutableValue = StaticSubstitution.mutableValue;
        try {
            StaticSubstitution.mutableValue = 0;
            StaticSubstitutionExamples staticSubstitutionExamples = new StaticSubstitutionExamples();
            
            int actual = staticSubstitutionExamples.lessThanZero();
            
            assertEquals(0, actual);
        } finally {
            StaticSubstitution.mutableValue = prevMutableValue;
        }
    }
    
    /**
    <pre>
    Test executes conditions:
 *     {@code (value > 0): True }
 * returns from: {@code return value > 0 ? value : 0; }
 * </pre>
     */
    @Test
    @DisplayName("lessThanZero: value > 0 : True -> return value > 0 ? value : 0")
    public void testLessThanZero_ValueGreaterThanZero() {
        int prevMutableValue = StaticSubstitution.mutableValue;
        try {
            StaticSubstitution.mutableValue = 1;
            StaticSubstitutionExamples staticSubstitutionExamples = new StaticSubstitutionExamples();
            
            int actual = staticSubstitutionExamples.lessThanZero();
            
            assertEquals(1, actual);
        } finally {
            StaticSubstitution.mutableValue = prevMutableValue;
        }
    }
    ///endregion
    
    ///endregion
}

Generated parametrized test looks like this:

public class StaticSubstitutionExamplesGeneratedTest {
    ///region Test suites for executable org.utbot.examples.statics.substitution.StaticSubstitutionExamples.lessThanZero
    
    ///region Parameterized test for method lessThanZero()
    
    @ParameterizedTest
    @MethodSource("provideDataForLessThanZero")
    public void parameterizedTestsForLessThanZero(StaticSubstitutionExamples staticSubstitutionExamples, Integer expectedResult) {
        int actual = staticSubstitutionExamples.lessThanZero();
        
        
        assertEquals(expectedResult, actual);
    }
    ///endregion
    
    ///endregion
    
    ///region Data providers and utils methods
    
    public static java.util.ArrayList<org.junit.jupiter.params.provider.Arguments> provideDataForLessThanZero() {
        java.util.ArrayList<org.junit.jupiter.params.provider.Arguments> argList = new java.util.ArrayList<org.junit.jupiter.params.provider.Arguments>();
        
        {
            StaticSubstitutionExamples staticSubstitutionExamples = new StaticSubstitutionExamples();
            
            argList.add(org.junit.jupiter.params.provider.Arguments.arguments(staticSubstitutionExamples, 0));
        }
        {
            StaticSubstitutionExamples staticSubstitutionExamples = new StaticSubstitutionExamples();
            
            argList.add(org.junit.jupiter.params.provider.Arguments.arguments(staticSubstitutionExamples, 1));
        }
        
        return argList;
    }
    ///endregion
}

NotNullAnnotation:

Generated not parametrized test looks like this:

public class NotNullAnnotationGeneratedTest {
    ///region Test suites for executable org.utbot.examples.annotations.NotNullAnnotation.notNullStaticField
    
    ///region
    
    /**
      */
    @Test
    @DisplayName("notNullStaticField: ")
    public void testNotNullStaticField() throws ClassNotFoundException, IllegalAccessException, NoSuchFieldException  {
        Class classWithRefFieldClazz = Class.forName("org.utbot.examples.annotations.ClassWithRefField");
        Integer prevStaticBoxedInt = ((Integer) getStaticFieldValue(classWithRefFieldClazz, "staticBoxedInt"));
        try {
            Integer staticBoxedInt = 0;
            setStaticField(classWithRefFieldClazz, "staticBoxedInt", staticBoxedInt);
            NotNullAnnotation notNullAnnotation = new NotNullAnnotation();
            
            int actual = notNullAnnotation.notNullStaticField();
            
            assertEquals(0, actual);
        } finally {
            setStaticField(ClassWithRefField.class, "staticBoxedInt", prevStaticBoxedInt);
        }
    }
    ///endregion
    
    ///endregion
    
    ///region Data providers and utils methods
    
    private static Object getStaticFieldValue(Class<?> clazz, String fieldName) throws IllegalAccessException, NoSuchFieldException {
        <...>
    }
    
    private static void setStaticField(Class<?> clazz, String fieldName, Object fieldValue) throws NoSuchFieldException, IllegalAccessException {
        <...>
    }
    ///endregion
}

Generated parametrized test looks like this:

public class NotNullAnnotationGeneratedTest {
    ///region Test suites for executable org.utbot.examples.annotations.NotNullAnnotation.notNullStaticField
    
    ///region Parameterized test for method notNullStaticField()
    
    @ParameterizedTest
    @MethodSource("provideDataForNotNullStaticField")
    public void parameterizedTestsForNotNullStaticField(NotNullAnnotation notNullAnnotation, Integer expectedResult) {
        int actual = notNullAnnotation.notNullStaticField();
        
        
        assertEquals(expectedResult, actual);
    }
    ///endregion
    
    ///endregion
    
    ///region Data providers and utils methods
    
    public static java.util.ArrayList<org.junit.jupiter.params.provider.Arguments> provideDataForNotNullStaticField() {
        java.util.ArrayList<org.junit.jupiter.params.provider.Arguments> argList = new java.util.ArrayList<org.junit.jupiter.params.provider.Arguments>();
        
        {
            NotNullAnnotation notNullAnnotation = new NotNullAnnotation();
            
            argList.add(org.junit.jupiter.params.provider.Arguments.arguments(notNullAnnotation, 0));
        }
        
        return argList;
    }
    ///endregion
}

UnsafeWithFieldTest:

Generated not parametrized test looks like this:

public class UnsafeWithFieldGeneratedTest {
    ///region Test suites for executable org.utbot.examples.unsafe.UnsafeWithField.setField
    
    ///region
    
    /**
    <pre>
    Test returns from: {@code return Field.INTEGER; }
 * </pre>
     */
    @Test
    @DisplayName("setField: -> return Field.INTEGER")
    public void testSetField_ReturnFieldINTEGER() throws ClassNotFoundException, IllegalAccessException, NoSuchFieldException  {
        NumberFormat.Field prevINTEGER = NumberFormat.Field.INTEGER;
        try {
            Class fieldClazz = Class.forName("java.text.NumberFormat$Field");
            setStaticField(fieldClazz, "INTEGER", null);
            UnsafeWithField unsafeWithField = new UnsafeWithField();
            
            NumberFormat.Field actual = unsafeWithField.setField(null);
            
            assertNull(actual);
        } finally {
            setStaticField(NumberFormat.Field.class, "INTEGER", prevINTEGER);
        }
    }
    ///endregion
    
    ///endregion
    
    ///region Data providers and utils methods
    
    private static void setStaticField(Class<?> clazz, String fieldName, Object fieldValue) throws NoSuchFieldException, IllegalAccessException {
        java.lang.reflect.Field field;
    
        do {
            try {
                field = clazz.getDeclaredField(fieldName);
            } catch (Exception e) {
                clazz = clazz.getSuperclass();
                field = null;
            }
        } while (field == null);
        
        java.lang.reflect.Field modifiersField = java.lang.reflect.Field.class.getDeclaredField("modifiers");
        modifiersField.setAccessible(true);
        modifiersField.setInt(field, field.getModifiers() & ~java.lang.reflect.Modifier.FINAL);
    
        field.setAccessible(true);
        field.set(null, fieldValue);
    }
    ///endregion
}

Generated parametrized test looks like this:

public class UnsafeWithFieldGeneratedTest {
    ///region Test suites for executable org.utbot.examples.unsafe.UnsafeWithField.setField
    
    ///region Parameterized test for method setField(java.text.NumberFormat.Field)
    
    @ParameterizedTest
    @MethodSource("provideDataForSetField")
    public void parameterizedTestsForSetField(UnsafeWithField unsafeWithField, NumberFormat.Field field, NumberFormat.Field expectedResult) {
        NumberFormat.Field actual = unsafeWithField.setField(field);
        
        if (expectedResult == null) {
            assertNull(actual);
        } else {
            
            assertNull(actual);
        }
    }
    ///endregion
    
    ///endregion
    
    ///region Data providers and utils methods
    
    public static java.util.ArrayList<org.junit.jupiter.params.provider.Arguments> provideDataForSetField() {
        java.util.ArrayList<org.junit.jupiter.params.provider.Arguments> argList = new java.util.ArrayList<org.junit.jupiter.params.provider.Arguments>();
        
        {
            UnsafeWithField unsafeWithField = new UnsafeWithField();
            
            argList.add(org.junit.jupiter.params.provider.Arguments.arguments(unsafeWithField, null, null));
        }
        
        return argList;
    }
    ///endregion
}

Visual proofs (screenshots, logs, images)

StaticsSubstitutionTest parametrized test:

image

NotNullAnnotationTest parametrized test:

image

UnsafeWithFieldTest parametrized test:

image

Additional Info
Cannot be reproduced with runIde (works fine there).

Metadata

Metadata

Labels

comp-codegenIssue is related to code generatorctg-bugIssue is a bug

Type

No type

Projects

Status

Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions