General
Tests should not be public
Instance variables should have no modifiers
Constants have to be
private static final
Instead of using ““ for master domains, use constant MASTER_DOMAIN for better readability
The test API should only be used for setting up the test case. Tested behavior should be implemented using the API of TASKANA.
Example: If creating a Task is the test case, then use
Task task = taskService.newTask(defaultWorkbasketSummary.getId()); task.setClassificationKey(defaultClassificationSummary.getKey()); task.setPrimaryObjRef(defaultObjectReference); task.setManualPriority(123); Task result = taskService.createTask(task);
instead of
Task task = TaskBuilder.newTask() .classificationSummary(defaultClassificationSummary) .workbasketSummary(defaultWorkbasketSummary) .primaryObjRef(defaultObjectReference) .manualPriority(123).buildAndStore(taskService);
If possible, getting entities from the database should be avoided by using return values.
Example:
Task task = createDefaultTask().manualPriority(123).buildAndStore(taskService); task.setManualPriority(42); Task result = taskService.updateTask(task);
instead of
Task task = createDefaultTask().manualPriority(123).buildAndStore(taskService); task.setManualPriority(42); taskService.updateTask(task); Task result = taskService.getTask(task.getId());
If tests throw any exception, they must throw
Exception.class
onlyTestclass name pattern:
rest: Start with the name of the tested class or description of the tested behavior, end with “IntTest” or “RestDocTest”, e.g.
TaskControllerIntTest
lib: Start with the name of the tested class or description of the tested behavior, end with “AccTest”, e.g.
UpdateTaskAccTest
Assertions
We are using AssertJ only
Concatenate the assertions if possible
We are strictly using the AssertJ fluent syntax. This means
assertThat(<testObject>).<operation>
examples:
BAD:assertThat(string.contains(“foo”)).isTrue();
GOOD:assertThat(string).contains(“foo”);
General Rule: Do not use any operation within the assertThat() function. Use existing functions from AssertJ’s assert classes.We want to use
extracting
instead of explicit extracting for collection-type entities.e.g.
assertThat(events) .extracting(WorkbasketHistoryEvent::getEventType) .containsExactly(WorkbasketHistoryEventType.DISTRIBUTION_TARGET_ADDED.getName());
instead of
type = events.get(0).getEventType(); assertThat(type).isEqualTo(WorkbasketHistoryEventType.DISTRIBUTION_TARGET_ADDED.getName());
Exceptions:
When checking for exceptions in our tests, we want to use one of the following methods:
Building an expected Exception and testing for equality with the thrown exception.
e.g.
Exception expectedException = new Exception(param1, param2, ...); assertThatThrownBy(() -> classificationService.createClassification(classification)) .usingRecursiveComparison().isEqualTo(expectedException);
Catching the exception thrown and checking if fields are set correctly through assertions.
e.g.
ThrowingCallable call = () -> classificationService.createClassification(classification); Exception e = catchThrowableOfType(call, Exception.class); assertThat(e.getX()).isEqualTo(X); assertThat(e.getY()).isEqualTo(Y);
Unit Tests
Test name pattern:
should_ExpectedBehavior_When_StateUnderTest
orshould_ExpectedBehavior_For_Situation
In case it is not possible to name the test with “when” or “for”, it is okay to writeshould_ExpectedBehaviour
. The most important thing is that the name is as understandable as possible.
Rest Tests
Url and HttpEntity should be extracted. The variables should be named
url
andauth
:String url = restHelper.toUrl(RestEndpoints.URL_ACCESS_ID) + "?search-for=cn=ksc-users,cn=groups,OU=Test,O=TASKANA"; HttpEntity<?> auth = restHelper.defaultRequest(); ResponseEntity<List<AccessIdRepresentationModel>> response = TEMPLATE.exchange( url, HttpMethod.GET, auth, ACCESS_ID_LIST_TYPE);
When testing our REST Service, we always use an
ObjectMapper
instance to convert an Object to a JSON representation. We NEVER create JSON Strings manually.