如何为集成测试创建模拟的 VaadinSession?

huangapple go评论76阅读模式
英文:

How to create mock VaadinSession for integration tests?

问题

我的问题:

这是我第一次为 Vaadin UI 编写测试,而且我对于单元测试也相对新手。我的问题是,我无法处理我的 UI 组件视图,因为没有 VaadinSession 来处理 UI bean。在使用 @SpringBootTest 时,不会创建 VaadinSession。我能够为后端创建测试,因为 Spring 处理了这些 bean,但是我似乎找不到方法来启动 Vaadin 会话,以便我可以访问会话并进行不同的集成和单元测试。

我尝试过的方法:

TestBench: Vaadin TestBench 似乎是一个很好的选择,但我遇到的问题是,每当我打开一个前往本地主机上网站的 ChromeDriver() 时,它似乎并不会打开 VaadinSession。

Karibu Library: 这个库似乎是一个很好的选择,但是有一个问题,就是它会打开被实例化的单独 UI 组件,然而我的一些 UI 组件类使用依赖注入来注入后端服务。由于依赖注入,我无法实例化这些类。

我需要通过 VaadinSession 访问的 UI 组件。

@Component
@UIScope
@CssImport("styles/current-info-styles.css")
public class CurrentDayView extends VerticalLayout implements Updatable {
    private static final long serialVersionUID = 1L;

    //一些代码在这里

    @Autowired
    public CurrentDayView(NowcastWeatherService nowcastWeatherService, GeoLocationService geoLocationService) {
        this.nowcastWeatherService = nowcastWeatherService;
        this.geoLocationService = geoLocationService;

        //一些代码在这里
    }
   //一些代码在这里

我的 Testbench 方法

@RunWith(SpringRunner.class)
@SpringBootTest
public class CurrentDayViewTest extends TestBenchTestCase {

    @Test
    public void fakeTest() {
        Assert.assertTrue(true);
    }

    @Before
    public void startUp() {
        System.setProperty("webdriver.chrome.driver", "src/main/resources/drivers/chromedriver.exe");
        setDriver(new ChromeDriver());
        getDriver().get("http://localhost:8080/");

        populateViewWithInformation();
    }

    @After
    public void tearDown() {
        getDriver().quit();
    }

    private void populateViewWithInformation() {
        CurrentDayView currentDayView = (CurrentDayView) VaadinSession.getCurrent().getAttribute("current-day-view");
        //这是我遇到问题的地方,因为 VaadinSession.getCurrent() 为 null
    }

我的最终问题:

有人知道我如何创建 VaadinSession,或者至少让 Spring 跟踪 Vaadin UI 组件吗?如果问题不清楚,请随时提问以获取更多关于我的问题的澄清信息。

英文:

My Issue:

This is my first time doing tests for Vaadin UI and I am also fairly new to Unit tests in general. My issue is that I can't do anything with my UI components Views because there is no VaadinSession which handles the UI beans. A VaadinSession is never created when using @SpringBootTest. I was able to create tests for my backend since Spring handles those beans, but I can't seem to figure out a way to get Vaadin to start up a session so I can then access the session and do different integration and unit tests.

What I've Tried

TestBench: The Vaadin testbench seemed like a very good option but the issue that I faced was that it doesn't seem to open a VaadinSession whenever I open a ChromeDriver() that goes to the website on my localhost.

Karibu Library: This library seemed like a very good option, but there was one issue, which was that it opens individual UI components that are instantiated, however a couple of my UI Components Classes, uses dependency injection to inject backend services. I cannot instantiate these classes because of the dependeny injection.

The UI Component that I need to access through the VaadinSession.

@Component
@UIScope
@CssImport("./styles/current-info-styles.css")
public class CurrentDayView extends VerticalLayout implements Updatable {
    private static final long serialVersionUID = 1L;

    //Some code here

    @Autowired
    public CurrentDayView(NowcastWeatherService nowcastWeatherService, GeoLocationService geoLocationService) {
        this.nowcastWeatherService = nowcastWeatherService;
        this.geoLocationService = geoLocationService;

        //Some Code here
    }
   //Some code here

My Testbench approach

@RunWith(SpringRunner.class)
@SpringBootTest
public class CurrentDayViewTest extends TestBenchTestCase {

    @Test
    public void fakeTest() {
        Assert.assertTrue(true);
    }

    @Before
    public void startUp() {
        System.setProperty("webdriver.chrome.driver", "src/main/resources/drivers/chromedriver.exe");
        setDriver(new ChromeDriver());
        getDriver().get("http://localhost:8080/");

        populateViewWithInformation();
    }

    @After
    public void tearDown() {
        getDriver().quit();
    }

    private void populateViewWithInformation() {
        CurrentDayView currentDayView = (CurrentDayView) VaadinSession.getCurrent().getAttribute("current-day-view");
        //This is where I get an error because VaadinSession.getCurrent() is null
    }

My Final Question:

Does anyone have any idea on how I could have a VaadinSession created or atleast get spring to keep track for Vaadin UI components? If this wasn't clear then please feel free to ask more clarifications relating to my question.

答案1

得分: 2

我建议你再试试Karibu,它非常适合进行这些不需要应用程序运行的测试。

看一下Karibu V14 Spring演示项目。注意使用了哪个Karibu依赖。ApplicationTest#listOrders测试包含导航到一个带有自动连线依赖项的视图。

你的TestBench测试存在问题,因为TestBench用于针对正在运行的应用程序进行测试,而这些测试在与实际应用程序完全不同的进程中运行。

因此,当你用驱动程序打开页面时,在应用程序中会创建一个Vaadin会话,但你将无法在测试中访问它,也无法访问任何UI状态或视图。然而,它允许你像通过浏览器与应用程序交互一样(点击按钮,填写文本字段等),并且在不了解服务器内部状态的情况下,检查浏览器中的状态是否正确。

英文:

I suggest you give Karibu another shot, it's great for doing these kinds of tests that don't need the app to be running.

Take a look at the Karibu V14 Spring demo project. Pay attention to what Karibu dependency is used. The ApplicationTest#listOrders test contains navigation to a view with autowired dependencies.

The issue with your TestBench test is that TestBench is used to test against a running application, and the tests run in an entirely different process than the actual application.

So when you open the page with the driver, a Vaadin session is created in the application, but you will not be able to access it in your tests, nor will you be able to access any UI state or views. What it allows you to do, however, is to interact with the application as you would do through the browser (clicking buttons, filling in text fields etc.), and to check that the state in the browser is correct, without knowing anything about the server's internal state.

答案2

得分: 1

通常来说,当你使用基于Selenium的TestBench编写集成测试时,你所做的就是控制浏览器。是的,你在编写Java代码,而且这些代码甚至可以与你的Vaadin UI代码在同一个项目中,但它可以针对任何URL执行,并且你正在与浏览器的DOM进行交互。你在描述最终用户的操作:点击按钮,在输入字段中输入文本,从单选按钮组中选择选项。服务器端就像是一个黑盒子。毕竟,如果我在StackOverflow上发布帖子,我不能检查它是否被存储在数据库中,我能做的只是查看我在按下“发布回答”按钮后看到的内容。如果你真的想挑剔的话,你甚至不需要使用Vaadin应用程序来进行TestBench测试,只要这个应用程序在浏览器中的行为类似于Vaadin应用即可。

其次,不应该将任何组件存储在VaadinSession中。如果你在多个浏览器选项卡中打开Vaadin应用程序,这些选项卡中的每一个都会共享相同的VaadinSession。单个组件实例应仅在一个浏览器选项卡内使用,其中根组件是当前的UI。

英文:

Generally speaking, when you're writing integration tests with TestBench (which is based on Selenium), what you're doing is directing the browser. You're writing Java code, yes, and the code may even be in the same project as your Vaadin UI code, but it can be executed against any URL and what you're interacting with is the browser's DOM. You're describing what the end-user would do: click a button, write some text in an input field, choose an option from a radio button group. The server-side is a black box. After all, if I submit a post on StackOverflow, I can't check if it gets stored in a database - all I can do is look at what I see after I press the "Post your answer" button. If you really want to nitpick, it doesn't even need to be a Vaadin application you're testing with TestBench, as long as the application behaves like one in the browser.

Secondly, you shouldn't store any Components in the VaadinSession. If you open a Vaadin application in multiple browser tabs, each of those tabs will share the same VaadinSession. A single Component instance should only be used inside one browser tab, where the root component is the current UI.

huangapple
  • 本文由 发表于 2020年9月17日 08:11:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/63929516.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定