Business data in integration tests

Validating the values of business data during the execution of a process is one of the main purposes of integration tests.

The Bonita Test Toolkit offers two possibilities to retrieve Business data:

  • From a process instance at any time during a test, so their values can be validated as much as necessary to ensure that the process behaves correctly.

  • Directly from the BDM database. It is different because these business data are not retrieved according to a specific case, but using existing queries (default or custom).

Integrations tests are built upon the Bonita Test Toolkit, based on the open-source Bonita Java Client.
The Bonita Test Toolkit is only available for Enterprise, Performance, Efficiency, and Teamwork. editions.

Delete BDM content

In order to have reproducible tests you may want to delete the content of the BDM on the target runtime before running a test.

@BonitaTests
class ProcessIT {

    @BeforeEach
    void deleteBDMContent(BonitaTestToolkit toolkit){
        toolkit.deleteBDMContent(); (1)
    }

}
1 This will delete the content of the BDM on the target runtime. Be careful to never execute your tests on a production environment !

Retrieve the value of a business data from a process instance

A business data is defined at the process level, it represents a business object from the Business Data Model.

It can be retrieved at any time during a test from the corresponding process instance, archived or not.

There are two ways to retrieve the value of a business data:

  • As a generic Object BusinessData

  • As a typed Object T representing your business object

The first method is the default one, it doesn’t require any additional development to be used and it is fully functional.
The second one is a bit more expensive since it requires a Java model matching the Business Data Model, but then it eases the use of the business data by providing direct access to the fields.

As a generic Object

Any business data can be retrieved as a generic Object using its name. The generic Object BusinessData gives access to the fields generically: it uses the name and the type of the field to retrieve it.

@BonitaTests
class ProcessIT {

    @Test
    void retrieve_business_data(BonitaTestToolkit toolkit) {
        User user = toolkit.getUser("walter.bates");
        ProcessDefinition processDef = toolkit.getProcessDefinition("myProcess");
        ProcessInstance processInstance = processDef.startProcessFor(user);

        BusinessData parentObjectData = processInstance.getBusinessData("parentObject"); (1)

        BusinessData singleRef = parentObjectData.getReference("singleRef"); (2)

        Integer intField = singleRef.getIntegerField("intField"); (3)
        LocalDate localDateField = singleRef.getLocalDateField("dateOnlyField"); (4)
        List<Long> multipleLongField = singleRef.getMultipleLongField("multiLongField"); (5)
    }
}
1 A business data is retrieved from the process instance as a generic object, using the business data name.
2 A complex field is retrieved from the generic business data: the method getReference is used to indicate that the field to retrieve is a reference (i.e a complex field), and the name of the field is passed to the method. Lazy and eager references are retrieved the same way.
3 An integer field is retrieved from the previous reference, using the appropriate method and the name of the field.
4 A local date field is retrieved from the previous reference, using the appropriate method and the name of the field.
5 A multiple long field is retrieved from the previous reference, using the appropriate method and the name of the field. As the field is multiple, the returned value is a list.

As a typed Object

To retrieve a business data as a typed Object, a Java model matching the BDM is required.
This eases the use of the business data since fields are retrieved using direct methods (no need to pass the name and the type of a field to get it), but it can increase the maintenance cost: each time the BDM is updated, the Java model might need to be updated too.

The Java model has to contain getters for all the fields in the BDM.
Those getter names must match the field names correctly: myFieldgetMyField().

@BonitaTests
class ProcessIT {

    interface TestBusinessDataModel { (1)

        interface ParentObject {

            long getPersistenceId();

            ChildReference getSingleRef();
        }

        interface ChildReference {

            long getPersistenceId();

            Integer getIntegerField();

            LocalDate getLocalDateField();

            List<Long> getMultipleLongField();
        }
    }

    @Test
    void retrieve_business_data(BonitaTestToolkit toolkit) {
        User user = toolkit.getUser("walter.bates");
        ProcessDefinition processDef = toolkit.getProcessDefinition("myProcess");
        ProcessInstance processInstance = processDef.startProcessFor(user);

        ParentObject typedParentObjectData = processInstance.getBusinessData("parentObject", ParentObject.class); (2)

        ChildReference typedSingleRef = typedParentObjectData.getSingleRef(); (3)

        Integer intField = typedSingleRef.getIntegerField(); (4)
        LocalDate localDateField = typedSingleRef.getLocalDateField();
        List<Long> multipleLongField = typedSingleRef.getMultipleLongField();
    }

}
1 An Interface matching the Business Data Model is created.
2 A business data is retrieved from the process instance using its name and the type of the business data → An object of type ParentObject is returned.
3 The complex field singleRef is retrieved using the Java method getSingleRef(). An object of type ChildReference is returned.
4 All simple fields from the ChildReference object can be retrieved using the corresponding Java method.

Retrieve business data using BDM queries

The Bonita test toolkit offers the possibility to create a DAO (Data Access Object) for all business objects defined in the business data model. These DAO can be generic or typed, and give the possibility to retrieve business data from the BDM database using queries (default or custom).

The difference between using a generic or a typed dao is the same as for business data retrieved from process instances:
Whereas the generic option doesn’t require any development and is fully functional, the typed option requires the development of a Java model matching the business data model, but objects returned by the queries will be correctly typed.

Using a generic DAO

A generic DAO can be created at any time from the bonita test toolkit. It requires the fully qualified name of the associated business object, and then gives access to the query generically. The business data returned by the queries are also generic.

@BonitaTests
class ProcessIT {

    @Test
    void retrieve_business_data_through_dao(BonitaTestToolkit toolkit) {
        BusinessObjectDAO<BusinessData> parentObjectDAO = toolkit.getBusinessObjectDAO("com.company.model.MyObject"); (1)

        List<BusinessData> findResult = parentObjectDAO.find(0, 100);(2)
        BusinessData singleQueryResult = parentObjectDAO.querySingle("singleQueryName", List.of(QueryParameter.stringParameter("parameterName", "value"))); (3)
        List<BusinessData> multipleQueryResult = parentObjectDAO.query("multipleQueryName", List.of(QueryParameter.stringParameter("parameterName", "value")), 0, 100); (4)

        Integer countForFind = parentObjectDAO.querySingle("countForFind", Integer.class); (5)

        assertThatThrownBy(() -> parentObjectDAO.querySingle("countForFind")).isInstanceOf(BusinessDataQueryException.class); (6)
    }
}
1 A generic DAO is retrieved from the toolkit using the business object fully qualified name.
2 Call the default query find using the dedicated method, to retrieve the first 100 business data.
3 Call the single query singleQueryName which returns a single value. This query has one parameter.
4 Call the query multipleQueryName which returns a list. This query has one parameter.
5 Call the single query countForFind. This query is a count, it counts the number of values that would be returned by the associated query. The return type (Integer) has to be passed to the generic DAO for count queries.
6 If the return type is not explicitly set for a count query an error is thrown.

Using a typed DAO

A typed DAO works in the exact same way as a generic DAO, but the returned objects are typed correctly.
A typed DAO can be created at any time using the Bonita Test Toolkit. It requires the type and the fully qualified name of the associated business object.

@BonitaTests
class ProcessIT {

    interface MyObject { (1)

        long getPersistenceId();

        Integer getIntegerField();

        LocalDate getLocalDateField();

        List<Long> getMultipleLongField();
    }

    @Test
    void retrieve_business_data_through_dao(BonitaTestToolkit toolkit) {
        BusinessObjectDAO<MyObject> parentObjectDAO = toolkit.getBusinessObjectDAO("com.company.model.MyObject", MyObject.class); (2)

        List<MyObject> findResult = parentObjectDAO.find(0, 100);(3)
        MyObject singleQueryResult = parentObjectDAO.querySingle("singleQueryName", List.of(QueryParameter.stringParameter("parameterName","value"))); (4)
        ...
    }
}
1 An Interface matching the Business Data Model is created.
2 A typed DAO is created using the fully qualified name of the business object and the type of the object in the test Java model.
3 The query find is called, a list of MyObject is returned.
4 The single query singleQueryName is called, an object MyObject is returned.

Query parameters

Use the factories methods from com.bonitasoft.test.toolkit.model.QueryParameter to instantiate typed query parameters. The supported parameter types are the same as the one that can be defined in a query from the BDM editor in the Studio.

var result = dao.query("myQuery",
					List.of(QueryParameter.stringParameter("stringParameterName","stringValue"),
							QueryParameter.integerParameter("intParameterName", 42),
							QueryParameter.stringsParameter("stringsParameterName", List.of("A", "B", "C")))),
					0, 100);
Supported parameter types
Parameter Type Factory Method

java.lang.String

QueryParameter.stringParameter

java.lang.Boolean

QueryParameter.booleanParameter

java.lang.Integer

QueryParameter.integerParameter

java.lang.Long

QueryParameter.longParameter

java.lang.Float

QueryParameter.floatParameter

java.lang.Double

QueryParameter.doubleParameter

java.util.Date

QueryParameter.dateParameter

java.time.LocalDate

QueryParameter.localDateParameter

java.time.LocalDateTime

QueryParameter.localDateTimeParameter

java.time.OffsetDateTime

QueryParameter.offsetDateTimeParameter

java.lang.String[]

QueryParameter.stringsParameter

java.lang.Integer[]

QueryParameter.integersParameter

java.lang.Float[]

QueryParameter.floatsParameter

java.lang.Double[]

QueryParameter.doublesParameter

java.lang.Long[]

QueryParameter.longsParameter