-
Notifications
You must be signed in to change notification settings - Fork 59
Using Matchers
Flinkspector uses the Matcher
interface from hamcrest. All Matchers provided by the framework implement Matcher<Iterable<OUT>>
where OUT
is the type of output records the data flow under test is producing. You can plugin any hamcrest matcher working with Iterable<OUT>
:
import static org.hamcrest.Matchers.*;
//...
assertDataSet(dataSet, hasItem(Tuple2.of("value","key")));
You can apply matchers in your tests in two ways. The first is to create a TestOutputFormat
or TestSink
:
TestOutputFormat<Tuple2<String,String> outputFormat =
createTestOutputFormat(hasItem(Tuple2.of("value","key")));
dataSet.output(outputFormat);
//for data stream:
TestSink<Tuple2<String,String>> sink =
createTestSink(hasItem(Tuple2.of("value","key")))
dataStream.addSink(outputFormat);
The output format or sink will feed the matcher with the output of the data flow.
The second way to use a matcher on a DataSet
or DataStream
is:
assertDataSet(dataSet, hasItem(Tuple2.of("value","key")));
assertDataStream(dataStream, hasItem(Tuple2.of("value","key")));
In the background the framework also creates a TestOutputFormat
or TestSink
and adds it to the data flow,
but tests become easier to read using the assert statements.
For simple test cases where you just want to check if the output contains a collection of records, the best way is to use ExpectedRecords
:
ExpectedRecords<String> expected = ExpectedRecords
.create("Peter")
.expect("Linda"))
.expect("Klaus");
// refine your expectations by adding requirements
output.refine().only();
The full documentation of this matcher can be found here: ExpectedRecords matcher.
If you're testing data flows producing long tuples, but only are interested in certain values. Or you wan't to apply matchers to single values in your output. Utilize AssertBlock
:
OutputMatcher<Tuple2<String, Integer>> matcher =
//name the values in your tuple with keys:
new MatchTuples<Tuple2<String, Integer>>("name", "value")
//add an assertion using a value and hamcrest matchers
.assertThat("name", isA(String.class))
.assertThat("value", lessThan(5))
.anyOfThem().onEachRecord();
The full documentation of this matcher can be found here: MatchTuples matcher. If your output is not in tuple form but you like to use this matcher check out: Input Output Translation.
ExpectedRecords
and MatchTuples
both produce a hamcrest matcher, so you can utilize hamcrest's library to combine these matchers with another:
import static org.hamcrest.Matchers.*;
//...
ExpectedRecords<Tuple2<String, Integer>> output = ExpectedRecords
.create(Tuple2.of("test", 1))
.expect(Tuple2.of("why", 2))
.expect(Tuple2.of("not", 3));
OutputMatcher<Tuple2<String, Integer>> matcher =
new MatchTuples<Tuple2<String, Integer>>("name", "value")
.assertThat("name", isA(String.class))
.assertThat("value", lessThan(5))
.onEachRecord();
//combine with anyOf()
assertStream(dataStream, allOf(output, hasItem(Tuple2("why",2)), matcher));
For more information on combining hamcrest matchers check out: Matchers.