package org.testory; import static java.util.Objects.deepEquals; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotSame; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.testory.Testory.given; import static org.testory.Testory.givenTest; import static org.testory.Testory.willReturn; import static org.testory.plumbing.inject.ArrayMaker.singletonArray; import static org.testory.plumbing.inject.ChainedMaker.chain; import static org.testory.plumbing.inject.FinalMaker.finalMaker; import static org.testory.plumbing.inject.RandomPrimitiveMaker.randomPrimitiveMaker; import static org.testory.testing.HamcrestMatchers.hasMessageContaining; import static org.testory.testing.Reflections.readDeclaredFields; import java.lang.annotation.ElementType; import java.lang.reflect.Array; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; import org.junit.Test; import org.testory.plumbing.Maker; import org.testory.proxy.Invocation; import org.testory.proxy.InvocationMatcher; public class TestGivenTest { private static final String string = "string"; private static final Maker maker = singletonArray(chain(randomPrimitiveMaker(), finalMaker())); private List<Object> fields; @Test public void injects_mock_of_concrete_class() { class ConcreteClass {} class TestClass { @SuppressWarnings("unused") ConcreteClass a, b, c, d, e, f, g, h, i, j; } TestClass test = new TestClass(); givenTest(test); assertContainsMocks(test); } @Test public void injects_mock_of_interface() { class TestClass { @SuppressWarnings("unused") Interface a, b, c, d, e, f, g, h, i, j; } TestClass test = new TestClass(); givenTest(test); assertContainsMocks(test); } @Test public void injects_mock_of_abstract_class() { abstract class AbstractClass {} class TestClass { @SuppressWarnings("unused") AbstractClass a, b, c, d, e, f, g, h, i, j; } TestClass test = new TestClass(); givenTest(test); assertContainsMocks(test); } @Test public void injects_mock_of_object() { class TestClass { @SuppressWarnings("unused") Object a, b, c, d, e, f, g, h, i, j; } TestClass test = new TestClass(); givenTest(test); assertContainsMocks(test); } @Test public void injects_array_of_mocks() { class TestClass { Object[] objects; Object[][] deepObjects; } TestClass test = new TestClass(); givenTest(test); assertEquals(1, test.objects.length); assertNotNull(test.objects[0]); assertTrue(test.objects[0].equals(test.objects[0])); assertEquals("objects[0]", test.objects[0].toString()); assertEquals(1, test.deepObjects.length); assertEquals(1, test.deepObjects[0].length); assertNotNull(test.deepObjects[0][0]); assertTrue(test.deepObjects[0][0].equals(test.deepObjects[0][0])); assertEquals("deepObjects[0][0]", test.deepObjects[0][0].toString()); } @Test public void mock_to_string_is_prestubbed() { class TestClass { Object field; } TestClass test = new TestClass(); givenTest(test); assertEquals("field", test.field.toString()); } @Test public void mock_equals_is_prestubbed() { class TestClass { Object field, otherField; } TestClass test = new TestClass(); givenTest(test); assertTrue(test.field.equals(test.field)); assertFalse(test.field.equals(test.otherField)); assertFalse(test.otherField.equals(test.field)); assertFalse(test.field.equals(null)); } @Test public void mock_hashcode_is_prestubbed() { class TestClass { Object field, otherField; } TestClass test = new TestClass(); givenTest(test); assertEquals(test.field.hashCode(), test.field.hashCode()); assertTrue(test.field.hashCode() != test.otherField.hashCode()); } @Test public void mock_is_stubbable() { class TestClass { List<Object> field; } TestClass test = new TestClass(); givenTest(test); given(willReturn(string), onInstance(test.field)); assertEquals(string, test.field.get(0)); } @Test public void mock_is_restubbable() { class TestClass { Object field; } TestClass test = new TestClass(); givenTest(test); given(willReturn(string), onInstance(test.field)); assertEquals(string, test.field.toString()); } @Test public void injects_sample_boolean() { class TestClass { @SuppressWarnings("unused") boolean a, b, c, d, e, f, g, h, i, j; } TestClass test = new TestClass(); givenTest(test); assertContainsSamples(test); } @Test public void injects_sample_Boolean() { class TestClass { @SuppressWarnings("unused") boolean a, b, c, d, e, f, g, h, i, j; } TestClass test = new TestClass(); givenTest(test); assertContainsSamples(test); } @Test public void injects_sample_char() { class TestClass { @SuppressWarnings("unused") char a, b, c, d, e, f, g, h, i, j; } TestClass test = new TestClass(); givenTest(test); assertContainsSamples(test); } @Test public void injects_sample_Character() { class TestClass { @SuppressWarnings("unused") Character a, b, c, d, e, f, g, h, i, j; } TestClass test = new TestClass(); givenTest(test); assertContainsSamples(test); } @Test public void injects_sample_byte() { class TestClass { @SuppressWarnings("unused") byte a, b, c, d, e, f, g, h, i, j; } TestClass test = new TestClass(); givenTest(test); assertContainsSamples(test); } @Test public void injects_sample_Byte() { class TestClass { @SuppressWarnings("unused") Byte a, b, c, d, e, f, g, h, i, j; } TestClass test = new TestClass(); givenTest(test); assertContainsSamples(test); } @Test public void injects_sample_short() { class TestClass { @SuppressWarnings("unused") short a, b, c, d, e, f, g, h, i, j; } TestClass test = new TestClass(); givenTest(test); assertContainsSamples(test); } @Test public void injects_sample_Short() { class TestClass { @SuppressWarnings("unused") Short a, b, c, d, e, f, g, h, i, j; } TestClass test = new TestClass(); givenTest(test); assertContainsSamples(test); } @Test public void injects_sample_int() { class TestClass { @SuppressWarnings("unused") int a, b, c, d, e, f, g, h, i, j; } TestClass test = new TestClass(); givenTest(test); assertContainsSamples(test); } @Test public void injects_sample_Integer() { class TestClass { @SuppressWarnings("unused") Integer a, b, c, d, e, f, g, h, i, j; } TestClass test = new TestClass(); givenTest(test); assertContainsSamples(test); } @Test public void injects_sample_long() { class TestClass { @SuppressWarnings("unused") long a, b, c, d, e, f, g, h, i, j; } TestClass test = new TestClass(); givenTest(test); assertContainsSamples(test); } @Test public void injects_sample_Long() { class TestClass { @SuppressWarnings("unused") Long a, b, c, d, e, f, g, h, i, j; } TestClass test = new TestClass(); givenTest(test); assertContainsSamples(test); } @Test public void injects_sample_float() { class TestClass { @SuppressWarnings("unused") float a, b, c, d, e, f, g, h, i, j; } TestClass test = new TestClass(); givenTest(test); assertContainsSamples(test); } @Test public void injects_sample_Float() { class TestClass { @SuppressWarnings("unused") Float a, b, c, d, e, f, g, h, i, j; } TestClass test = new TestClass(); givenTest(test); assertContainsSamples(test); } @Test public void injects_sample_double() { class TestClass { @SuppressWarnings("unused") double a, b, c, d, e, f, g, h, i, j; } TestClass test = new TestClass(); givenTest(test); assertContainsSamples(test); } @Test public void injects_sample_Double() { class TestClass { @SuppressWarnings("unused") Double a, b, c, d, e, f, g, h, i, j; } TestClass test = new TestClass(); givenTest(test); assertContainsSamples(test); } @Test public void injects_sample_String() { class TestClass { @SuppressWarnings("unused") String a, b, c, d, e, f, g, h, i, j; } TestClass test = new TestClass(); givenTest(test); assertContainsSamples(test); } @Test public void injects_sample_Class() { class TestClass { @SuppressWarnings("unused") Class<?> a, b, c, d, e, f, g, h, i, j; } TestClass test = new TestClass(); givenTest(test); assertContainsSamples(test); } @Test public void injects_sample_Field() { class TestClass { @SuppressWarnings("unused") Field a, b, c, d, e, f, g, h, i, j; } TestClass test = new TestClass(); givenTest(test); assertContainsSamples(test); } @Test public void injects_sample_Method() { class TestClass { @SuppressWarnings("unused") Method a, b, c, d, e, f, g, h, i, j; } TestClass test = new TestClass(); givenTest(test); assertContainsSamples(test); } @Test public void injects_sample_Constructor() { class TestClass { @SuppressWarnings("unused") Constructor<?> a, b, c, d, e, f, g, h, i, j; } TestClass test = new TestClass(); givenTest(test); assertContainsSamples(test); } @Test public void injects_sample_boolean_array() { class TestClass { @SuppressWarnings("unused") boolean[] a, b, c, d, e, f, g, h, i, j; } TestClass test = new TestClass(); givenTest(test); assertContainArraysWithSamples(test); } @Test public void injects_sample_Boolean_array() { class TestClass { @SuppressWarnings("unused") Boolean[] a, b, c, d, e, f, g, h, i, j; } TestClass test = new TestClass(); givenTest(test); assertContainArraysWithSamples(test); } @Test public void injects_sample_char_array() { class TestClass { @SuppressWarnings("unused") char[] a, b, c, d, e, f, g, h, i, j; } TestClass test = new TestClass(); givenTest(test); assertContainArraysWithSamples(test); } @Test public void injects_sample_Character_array() { class TestClass { @SuppressWarnings("unused") Character[] a, b, c, d, e, f, g, h, i, j; } TestClass test = new TestClass(); givenTest(test); assertContainArraysWithSamples(test); } @Test public void injects_sample_byte_array() { class TestClass { @SuppressWarnings("unused") byte[] a, b, c, d, e, f, g, h, i, j; } TestClass test = new TestClass(); givenTest(test); assertContainArraysWithSamples(test); } @Test public void injects_sample_Byte_array() { class TestClass { @SuppressWarnings("unused") Byte[] a, b, c, d, e, f, g, h, i, j; } TestClass test = new TestClass(); givenTest(test); assertContainArraysWithSamples(test); } @Test public void injects_sample_short_array() { class TestClass { @SuppressWarnings("unused") short[] a, b, c, d, e, f, g, h, i, j; } TestClass test = new TestClass(); givenTest(test); assertContainArraysWithSamples(test); } @Test public void injects_sample_Short_array() { class TestClass { @SuppressWarnings("unused") Short[] a, b, c, d, e, f, g, h, i, j; } TestClass test = new TestClass(); givenTest(test); assertContainArraysWithSamples(test); } @Test public void injects_sample_int_array() { class TestClass { @SuppressWarnings("unused") int[] a, b, c, d, e, f, g, h, i, j; } TestClass test = new TestClass(); givenTest(test); assertContainArraysWithSamples(test); } @Test public void injects_sample_Integer_array() { class TestClass { @SuppressWarnings("unused") Integer[] a, b, c, d, e, f, g, h, i, j; } TestClass test = new TestClass(); givenTest(test); assertContainArraysWithSamples(test); } @Test public void injects_sample_long_array() { class TestClass { @SuppressWarnings("unused") long[] a, b, c, d, e, f, g, h, i, j; } TestClass test = new TestClass(); givenTest(test); assertContainArraysWithSamples(test); } @Test public void injects_sample_Long_array() { class TestClass { @SuppressWarnings("unused") Long[] a, b, c, d, e, f, g, h, i, j; } TestClass test = new TestClass(); givenTest(test); assertContainArraysWithSamples(test); } @Test public void injects_sample_float_array() { class TestClass { @SuppressWarnings("unused") float[] a, b, c, d, e, f, g, h, i, j; } TestClass test = new TestClass(); givenTest(test); assertContainArraysWithSamples(test); } @Test public void injects_sample_Float_array() { class TestClass { @SuppressWarnings("unused") Float[] a, b, c, d, e, f, g, h, i, j; } TestClass test = new TestClass(); givenTest(test); assertContainArraysWithSamples(test); } @Test public void injects_sample_double_array() { class TestClass { @SuppressWarnings("unused") double[] a, b, c, d, e, f, g, h, i, j; } TestClass test = new TestClass(); givenTest(test); assertContainArraysWithSamples(test); } @Test public void injects_sample_Double_array() { class TestClass { @SuppressWarnings("unused") Double[] a, b, c, d, e, f, g, h, i, j; } TestClass test = new TestClass(); givenTest(test); assertContainArraysWithSamples(test); } @Test public void injects_sample_String_array() throws IllegalAccessException { @SuppressWarnings("unused") class TestClass { String[] a, b, c, d, e, f, g, h, i, j; } TestClass test = new TestClass(); givenTest(test); assertContainArraysWithSamples(test); } @Test public void injects_sample_deep_String_array() { class TestClass { String[][] deepArray; } TestClass test = new TestClass(); givenTest(test); assertArrayEquals(new String[][] { { maker.make(String.class, "deepArray[0][0]") } }, test.deepArray); } @Test public void injects_sample_enum() { @SuppressWarnings("unused") class TestClass { ElementType a, b, c, d, e, f, g, h, i, j; } TestClass test = new TestClass(); givenTest(test); assertContainsSamples(test); } @Test public void skips_not_null() { @SuppressWarnings("unused") class TestClass { Object field = new Object(); String stringField = "value"; Boolean booleanField = Boolean.TRUE; Character characterField = Character.valueOf((char) 1); Byte byteField = Byte.valueOf((byte) 1); Short shortField = Short.valueOf((short) 1); Integer integerField = Integer.valueOf(1); Long longField = Long.valueOf(1); Float floatField = Float.valueOf(1); Double doubleField = Double.valueOf(1); } TestClass test = new TestClass(); fields = readDeclaredFields(test); givenTest(test); assertEquals(fields, readDeclaredFields(test)); } @Test public void skips_void() { class TestClass { Void voidField; } TestClass test = new TestClass(); givenTest(test); assertEquals(null, test.voidField); } @Test public void skips_primitive_not_equal_to_binary_zero() { @SuppressWarnings("unused") class TestClass { boolean booleanPrimitive = true; boolean booleanWrapper = true; char charField = 'a'; byte byteField = 1; short shortField = 1; int intField = 1; long longField = 1; float floatField = 1; double doubleField = 1; } TestClass test = new TestClass(); fields = readDeclaredFields(test); givenTest(test); assertEquals(fields, readDeclaredFields(test)); } static class TestClassWithStaticField { static Object field = null; } @Test public void skips_static_field() { TestClassWithStaticField test = new TestClassWithStaticField(); givenTest(test); assertNull(TestClassWithStaticField.field); } @Test public void skips_final_field() { class TestClass { final Object field = null; } TestClass test = new TestClass(); givenTest(test); assertNull(test.field); } @Test public void cannot_inject_final_class() { final class FinalClass {} class TestClass { @SuppressWarnings("unused") FinalClass fieldOfFinalClass; } TestClass test = new TestClass(); try { givenTest(test); fail(); } catch (TestoryException e) { assertThat(e, hasMessageContaining("fieldOfFinalClass")); } } private static void assertContainsMocks(Object instance) { try { for (Field field : injectableFields(instance.getClass())) { Object mock = field.get(instance); assertTrue(field.getType().isInstance(mock)); assertNotSame(field.getType(), mock.getClass()); } } catch (IllegalAccessException e) { throw new RuntimeException(e); } } private static void assertContainsSamples(Object instance) { try { for (Field field : injectableFields(instance.getClass())) { assertEquals(maker.make(field.getType(), field.getName()), field.get(instance)); } } catch (IllegalAccessException e) { throw new RuntimeException(e); } } private static void assertContainArraysWithSamples(Object instance) { try { for (Field field : injectableFields(instance.getClass())) { Object array = Array.newInstance(field.getType().getComponentType(), 1); Array.set(array, 0, maker.make(field.getType().getComponentType(), field.getName() + "[0]")); assertTrue(deepEquals(field.get(instance), array)); } } catch (IllegalAccessException e) { throw new RuntimeException(e); } } private static List<Field> injectableFields(Class<?> type) { List<Field> fields = new ArrayList<>(); for (Field field : type.getDeclaredFields()) { if (!field.isSynthetic()) { fields.add(field); } } return fields; } private static InvocationMatcher onInstance(final Object mock) { return new InvocationMatcher() { public boolean matches(Invocation invocation) { return invocation.instance == mock; } }; } public static interface Interface {} }