Zest™
Introduction
Tutorials
Javadoc
Samples
Core
Libraries
Extensions
Tools
Glossary 

Core Test Support

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.

Table 17. Artifact

Group IDArtifact IDVersion

org.qi4j.core

org.qi4j.core.testsupport

2.1


Your First Testcase

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.