I am writing some test code for a processElement
function in Apache Flink 1.4:
public class ProcessFunctionClass {
public void processElement(Tuple2<String, String> tuple2, Context context, Collector<Tuple2<String, String>> collector) {
// if the state is empty, start a timer
if (listState.get().iterator().hasNext() == false)
context.timerService().registerEventTimeTimer(1000);
listState.add("someStringToBeStored");
// ...
}
}
public class ProcessFunctionClassTest {
private ProcessFunctionClass processFunctionClass;
@Mock
private ListState<String> listState;
@Before
public void setUp() throws Exception {
processFunctionClass = new ProcessFunctionClass();
}
@Test
public void testProcessElement() {
ListState mockListState = mock(ListState.class);
Iterable mockIterable = mock(Iterable.class);
Iterator mockIterator = mock(Iterator.class);
MockitoAnnotations.initMocks(this);
when(tDPListState.get()).thenReturn(mockIterable);
when(tDPListState.get().iterator()).thenReturn(mockIterator);
when(tDPListState.get().iterator().hasNext()).thenReturn(false);
processFunctionClass.processElement(tuple2, context, collector);
// verify(...)
}
}
When I debug using my IDE, just before I step into the processElement()
method, listState
is not null
and appears to have been mocked successfully, but as soon as I get to listState.get().iterator().hasNext()
, listState
is null
and I get a NullPointerException. What am I doing wrong here?
In ProcessFunctionClass
you have a private listState
variable. In your test you create a completely unrelated mockListState
variable and set some expectations on it.
For your test to work, you must provide a way (constructor or setter) to set ProcessFunctionClass.listState
to desired value (your mocked list state)
On top of that, MockitoAnnotations.initMocks(this);
seems to do nothing in your example: you haven't shown us any fields annotated with @Mock
or @InjectMocks
Update
You are misusing @Mock
annotation. You should place it in the test class, not in class under test. When placed in the test class, after a call to initMocks, the filed will be initialized with a mock of an appropriate type.
What you should fo instead:
MockitoAnnotations.initMocks(this);
, you are creating all the mocks manually.ProcessFunctionClass
public ProcessFunctionClass(ListState<String> listState) {
this.listState = listState
}
var mockListState = mock(ListState.class);
var processFunctionClass = new ProcessFunctionClass();
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments