### Question:
FieldInjections { List<FieldSetter> setters( Class<?> cls ) throws ProcedureException { List<FieldSetter> setters = new LinkedList<>(); Class<?> currentClass = cls; do { for ( Field field : currentClass.getDeclaredFields() ) { if ( field.isSynthetic() ) { continue; } if ( Modifier.isStatic( field.getModifiers() ) ) { if ( field.isAnnotationPresent( Context.class ) ) { throw new ProcedureException( Status.Procedure.ProcedureRegistrationFailed, "The field `%s` in the class named `%s` is annotated as a @Context field,%n" + "but it is static. @Context fields must be public, non-final and non-static,%n" + "because they are reset each time a procedure is invoked.", field.getName(), cls.getSimpleName() ); } continue; } assertValidForInjection( cls, field ); setters.add( createInjector( cls, field ) ); } } while ( (currentClass = currentClass.getSuperclass()) != null ); return setters; } FieldInjections( ComponentRegistry components );   }### Answer:
@Test public void shouldNotAllowClassesWithNonInjectedFields() throws Throwable { FieldInjections injections = new FieldInjections( new ComponentRegistry() ); exception.expect( ProcedureException.class ); exception.expectMessage( "Field `someState` on `ProcedureWithNonInjectedMemberFields` " + "is not annotated as a @Context and is not static. " + "If you want to store state along with your procedure, " + "please use a static field." ); injections.setters( ProcedureWithNonInjectedMemberFields.class ); }
@Test public void shouldNotAllowNonPublicFieldsForInjection() throws Throwable { FieldInjections injections = new FieldInjections( new ComponentRegistry() ); exception.expect( ProcedureException.class ); exception.expectMessage( "Field `someState` on `ProcedureWithPrivateMemberField` must be non-final and public." ); injections.setters( ProcedureWithPrivateMemberField.class ); }
@Test public void staticFieldsAreAllowed() throws Throwable { FieldInjections injections = new FieldInjections( new ComponentRegistry() ); List<FieldInjections.FieldSetter> setters = injections.setters( ProcedureWithStaticFields.class ); assertEquals( 0, setters.size() ); }
@Test public void inheritanceIsAllowed() throws Throwable { ComponentRegistry components = new ComponentRegistry(); components.register( int.class, ctx -> 1337 ); FieldInjections injections = new FieldInjections( components ); List<FieldInjections.FieldSetter> setters = injections.setters( ChildProcedure.class ); ChildProcedure childProcedure = new ChildProcedure(); for ( FieldInjections.FieldSetter setter : setters ) { setter.apply( null, childProcedure ); } assertEquals( 1337, childProcedure.childField ); assertEquals( 1337, childProcedure.parentField ); }
@Test public void syntheticsAllowed() throws Throwable { ComponentRegistry components = new ComponentRegistry(); components.register( int.class, ctx -> 1337 ); FieldInjections injections = new FieldInjections( components ); List<FieldInjections.FieldSetter> setters = injections.setters( Outer.ClassWithSyntheticField.class ); Outer.ClassWithSyntheticField syntheticField = new Outer().classWithSyntheticField(); for ( FieldInjections.FieldSetter setter : setters ) { setter.apply( null, syntheticField ); } assertEquals( 1337, syntheticField.innerField ); }