Komponenty najlepiej testować z frameworkami TestNG oraz Mockito, gdyż istnieją one już w projekcie systemu. TestNG służy do tworzenia kolejnych testów jednostkowych, sprawdzania warunków, inicjalizacji testów, łapania pożądanych wyjątków itp. Mockito służy natomiast do tworzenia implementacji i wstrzykiwania obiektów, które są niezbędne do przetestowania niektórych funkcjonalności (np. gdy komponent używa systemowych serwisów ProcessService, UserService itp.).

Przykładowy datachooser korzystający z serwisu UserFinder:

@DataChooser
public class FindingUserDataChooser
{
    @Autowired
    private UserFinder userFinder;

    @Define
    public void definition( DataChooserDefinitionBuilder builder )
    {
        // @formatter:off
        builder
            .id( "finding-user-datachooser" )
            .name( "finding-user-datachooser-name" )
            .description( "finding-user-datachooser-desc" )
            .category( Categories.CUSTOM )
                .mapping()
                    .id( "fullname-mapping" )
                    .name( "fullname-mapping-name" )
                    .description( "fullname-mapping-desc" )
                    .create();
        // @formatter:on
    }

    public void data( ComponentQueryData queryData, DataChooserResult result )
    {
        String username = queryData.getQuery();

        DetachedCriteria criteria = DetachedCriteria.forClass( User.class );
        criteria.add( Restrictions.like( "userName", username ) );
        List<User> users = userFinder.findByCriteria( criteria );
        // itd...
    }
}

Do tak stworzonego komponentu zostanie wstrzyknięty przez adnotację @Autowired systemowy serwis UserFinder.

Aby używać systemowe serwisy we wtyczkach, należy zaimportować je również w deskryptorze wtyczki (Import i udostępnianie serwisów).

Przykładowy test powyższej klasy miałby postać:

@Test
public class FindingUserDataChooserTest
{
    @InjectMocks
    FindingUserDataChooser component = new FindingUserDataChooser();

    @Mock
    UserFinder userFinder;

    @Before
    private void init()
    {
        MockitoAnnotations.initMocks( this );
        when( userFinder.findByCriteria( any( DetachedCriteria.class ) ) ).thenReturn( getSampleUserList() );
    }

    private List<User> getSampleUserList()
    {
        User user1 = new User( "user1", "password" );
        User user2 = new User( "user2", "password" );
        return Lists.newArrayList( user1, user2 );
    }

    @Test
    private void componentTest()
    {
        // ...
    }
}

Serwis UserFinder został zmockowany przez adnotację @Mock. Statyczne metody when i thenReturn określają zachowanie się serwisu UserFinder dla konkretnych wywołań. Należy pamiętać, że nie jest to prawdziwy systemowy serwis, a jedynie tymczasowa implementacja na czas wykonywania testów. Adnotacja @InjectMocks mówi o tym, iż do stworzonego obiektu komponentu (FindingUserDataChooser) Mockito będzie próbował wstrzyknąć implementacje do jego pól (w tym przypadku wstrzyknie UserFindera).

Systemowe serwisy można również wstrzykiwać w komponentach przez stworzenie oznaczonego adnotacją @Autowired konstruktora posiadającego w parametrach kolejne serwisy. Przykładowy komponent:

@DataChooser
public class FindingUserDataChooser
{
    private UserFinder userFinder;

    @Autowired
    public FindingUserDataChooser( UserFinder userFinder )
    {
        this.userFinder = userFinder;
    }

    @Define
    public void definition( DataChooserDefinitionBuilder builder )
    {
        // @formatter:off
        builder
            .id( "finding-user-datachooser" )
            .name( "finding-user-datachooser-name" )
            .description( "finding-user-datachooser-desc" )
            .category( Categories.CUSTOM )
                .mapping()
                    .id( "fullname-mapping" )
                    .name( "fullname-mapping-name" )
                    .description( "fullname-mapping-desc" )
                    .create();
        // @formatter:on
    }

    public void data( ComponentQueryData queryData, DataChooserResult result )
    {
        String username = queryData.getQuery();
        DetachedCriteria criteria = DetachedCriteria.forClass( User.class );
        criteria.add( Restrictions.like( "userName", username ) );
        List<User> users = userFinder.findByCriteria( criteria );
        // itd.
    }
}

W takim przypadku również serwis UserFinder zostanie poprawnie zaciągnięty przez komponent. Komponent można przetestować w poniższy sposób:

@Test
public class FindingUserDataChooserTest
{
    FindingUserDataChooser component;

    @Mock
    UserFinder userFinder;

    @Before
    private void init()
    {
        MockitoAnnotations.initMocks( this );
        when( userFinder.findByCriteria( any( DetachedCriteria.class ) ) ).thenReturn( getSampleUserList() );
        component = new FindingUserDataChooser( userFinder );
    }

    private List<User> getSampleUserList()
    {
        User user1 = new User( "user1", "password" );
        User user2 = new User( "user2", "password" );
        return Lists.newArrayList( user1, user2 );
    }

    @Test
    private void componentTest()
    {
        // ...
    }
}

Pamiętać należy również, że do wywołania komponentów należy stworzyć specyficzne dla rodzaju komponentu obiekty. Przykładowo dla powyższego DataChoosera można zauważyć, iż metoda data przyjmuje obiekty ComponentQueryData oraz DataChooserResult, które w testach należy własnoręcznie stworzyć.