Vaadin 10+, How to trigger UI.getCurrent().access in kaributesting

Viewed 598

I want to test a Vaadin flow Component with karibu-testing. In this component I'm using UI.getCurrent().access {} to update this component but when running the test the code inside access won't be executed. The same result when I try to use UI.getCurrent().access {} in the test itself... Some ideas?

pom.xml

<dependency>
   <groupId>com.github.mvysny.kaributesting</groupId>
   <artifactId>karibu-testing-v10</artifactId>
   <version>1.1.4</version>
</dependency>

test (Kotlin)

class MyUITest {

    @BeforeAll
    fun init() {
        MockVaadin.setup()
    }

    @BeforeEach
    fun setup() {
        UI.getCurrent().removeAll()
    }

    @Test
    fun testSometing() {
        UI.getCurrent().access {
            print("foo") // this line is not reachable
        }
    }
}
1 Answers

I hope I didn't misunderstand your question. I tried to create a minimal example with a component that is using UI.getCurrent().access {} to change something in the UI.

Here I have a component with a single TextField in it with a value "hallo". There is a method inside that component which changes the TextField's value to "hey".

The component looks like

package com.example.test;

import com.vaadin.flow.component.Component;
import com.vaadin.flow.component.Tag;
import com.vaadin.flow.component.UI;
import com.vaadin.flow.component.textfield.TextField;
import com.vaadin.flow.server.Command;

@Tag(value = "myComponent")
public class MyComponent extends Component {
    private TextField textField = new TextField();

    public MyComponent() {
        textField.setValue("hallo");
    }

    public void changeValueToHey() {
        UI.getCurrent().access((Command) () -> {
            textField.setValue("hey");
        });
    }

    public String getTextFieldValue() {
        return textField.getValue();
    }
}

And then I created a karibu test (v. 1.1.6) like:

@Test
public void test() {
    MyComponent myComponent = new MyComponent();
    UI.getCurrent().add(myComponent);
    assertEquals("hallo", myComponent.getTextFieldValue());
    MockVaadin.INSTANCE.runUIQueue(true);
    myComponent.changeValueToHey();
    MockVaadin.INSTANCE.runUIQueue(true);
    assertEquals("hey", myComponent.getTextFieldValue());
}

I found those runUIQueue in the documentation (https://github.com/mvysny/karibu-testing/tree/master/karibu-testing-v10) where it is said:

The thing is that Karibu Testing runs the test with the UI lock held. That simplifies testing very much, but that also prevents async updates by another thread, simply because the test is holding the lock!

The solution is to briefly let loose of the UI lock in the testing thread, allowing UI.access() tasks posted from a background thread to be processed. Then the testing thread will re-obtain the lock and continue testing.

Related