David
David

Reputation: 123

Flutter BlocTest with KeyEvents

I want to simulate a key event press using blocTest for a Cubit function I'm testing. So far it doesn't seem like I can call simulateKeyDownEvent within BlocTest because it focuses on the Bloc/Cubit and not the widget. But when I mock a RawKeyDownEvent() event, isKeyPressed is returning false even if it's the correct mocked key?

Anyone know why this happens and how to get it to show true?

My cubit function uses this syntax:

void handleKeyPress(RawKeyEvent event) {
   if (event.isKeyPressed(LogicalKeyboardKey.keyU)) { ... }
...

Event mock and test:

blocTest<Cubit, State>('Handle key press, increase layer',
    build: () => cubit, // defined in setup
    act: (cubit) async {
      RawKeyEvent mockEnterKey = const RawKeyDownEventMock(
          data: RawKeyEventDataWindows(keyCode: 13, scanCode: 28, characterCodePoint: 0, modifiers: 0), character: 'enter')
        ..physicalKey = PhysicalKeyboardKey.enter
        ..logicalKey = LogicalKeyboardKey.enter;
      cubit.handleKeyPress(mockEnterKey);
    },
    expect: () => [isA<State>().having((state) => state.currentLayer, 'curent layer', initState + 1)]);

Event Mock defintion:

class RawKeyDownEventMock extends RawKeyEvent {
  const RawKeyDownEventMock({required data, String? character, bool repeat = false}) : super(data: data, character: character, repeat: repeat);
  set physicalKey(PhysicalKeyboardKey key) => key;
  set logicalKey(LogicalKeyboardKey key) => key;
  @override
  bool isKeyPressed(LogicalKeyboardKey key) {
    // Showing as false in tests even when simulating key
    // logical key id - name - physical key id
    // 4294967309 - enter - 458792
    // 117 - U - 458776
    // 97 - A - 458756
    // if (key.keyId == 4294967309 || key.keyId == 117 || key.keyId == 97) return true;
    return super.isKeyPressed(key);
  }
}

Upvotes: 0

Views: 198

Answers (1)

David
David

Reputation: 123

It ended being that the keysPressed Set in the instance of RawKeyboard in raw_keyboard.dart hadn't added the RawKeyEvent to itself because the handleRawKeyEvent function was never triggered.

So you just have to call await simulateKeyDownEvent(LogicalKeyboardKey.enter, physicalKey: PhysicalKeyboardKey.enter) // or key or your choice

I was doing a lot by Mocking the RawKeyEvent function and, in theory, I think you could still use it and manipulate the RawKeyboard instance and manually call the handleRawKeyEvent function, but that seems like overkill. Fun learning exercise I guess though.

Upvotes: 0

Related Questions