code
docs
tests
Zest™ comes with classes to help with testing. For general development, only a couple of classes are of interest as the others are mostly for EntityStore and Index/Query SPI implementations. There is also some mocking support, to allow some of Zest’s unique aspects to be mocked, but since Zest™ is so flexible at a fine-granular level, we have found that mocking is seldom, if ever, needed.
In most cases, you will probably use the AbstractQi4jTest class to simplify starting a Zest™ test instance.
public class HelloTest extends AbstractQi4jTest { [...snip...] }
This will do all the initialization of a Zest™ runtime instance and create a single layer with a single module in it. What goes into that module is declared in the assembly() method;
@Override public void assemble( ModuleAssembly module ) throws AssemblyException { module.values( Hello.class ); }
In this case we declare that we have a ValueComposite of type org.qi4j.tutorials.hello.Hello which looks like
/** * This Composite interface declares a simple "Hello World" interface with a single say() method. What is being * said is defined in the HelloWorldState interface, which is a private mixin. */ @Mixins( { Hello.HelloWorldMixin.class } ) public interface Hello { String say(); /** * This is the implementation of the say() method. */ public abstract class HelloWorldMixin implements Hello { // @This reference the composite itself, and since HelloWorldState is not part of the public interface, // it is a private mixin. @This private State state; @Override public String say() { return state.phrase().get() + " " + state.name().get(); } } /** * This interface contains only the state of the HelloWorld object. */ public interface State { @NotEmpty @UseDefaults Property<String> phrase(); @NotEmpty @UseDefaults Property<String> name(); } }
The say() method will get the phrase and name from its internal state (the State interface is not magical, it could be named anything).
And then we create the actual test;
@Test public void givenHelloValueInitializedToHelloWorldWhenCallingSayExpectHelloWorld() { ValueBuilder<Hello> builder = module.newValueBuilder( Hello.class ); builder.prototypeFor( Hello.State.class ).phrase().set( "Hello" ); builder.prototypeFor( Hello.State.class ).name().set( "World" ); Hello underTest = builder.newInstance(); String result = underTest.say(); assertThat( result, equalTo( "Hello World" ) ); }
By using the prototypeFor() we can access the hidden, internal and very private state of the ValueComposite. Once the value is created we can reach this directly.