如何正确测试JavaFX中返回Task对象的方法?

uqjltbpv  于 2023-04-19  发布在  Java
关注(0)|答案(1)|浏览(112)

我面临的问题测试方法,返回任务对象的javafx.concurrent.Task包.当我运行测试,程序中止,它无法创建新的BasicDataSource对象,甚至没有抛出任何异常,测试通过太.所以很难跟踪确切的问题.我的意思是,它可能是有关线程,但不完全确定.
连接池代码段(问题源自此处):

public synchronized static DataSource getDataSource() {

        try {

            Properties property = new Properties();
            URL url = SessionManager.class.getResource("/properties/database.properties");
            property.load(new FileInputStream(Objects.requireNonNull(url).getFile()));
            if (dataSource == null) {
                synchronized (ConnectionPool.class) {

                    if (dataSource == null)
                        dataSource = new BasicDataSource(); //Program aborts here
                }
            }
            
            dataSource.setUrl(property.getProperty("DB_URL"));
            dataSource.setUsername(property.getProperty("DB_USERNAME"));
            dataSource.setPassword(property.getProperty("DB_PASSWORD"));
            dataSource.setMaxTotal(Integer.parseInt(property.getProperty("DB_MAX_CONNECTIONS")));
            dataSource.setMaxOpenPreparedStatements(Integer.parseInt(property.getProperty("DB_MAX_PREPARED_STATEMENTS")));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return dataSource;
    }

Junit 5测试片段:

@BeforeAll
    static void initJavaFxToolkit() {

        // Initialize the JavaFX toolkit
        Platform.startup(() -> {
        });
    }

    @AfterAll
    static void tearDown() {

        Platform.exit();
    }

    @Test
    @DisplayName("Test if user credentials pass on correct credentials")
    void testIfUserCredentialsPassOnCorrectCredentials() {

        LoginCredentials loginCredentials = new LoginCredentials("organization", "Hello123#", true);
        Validator login = new Login(loginCredentials);

        Task<AuthenticationStatus> task = login.getUserValidationStatus();
        Platform.runLater(() -> task.setOnSucceeded(workerStateEvent -> assertEquals(AuthenticationStatus.SUCCESS, task.getValue())));
    }

第一次调用getDataSource()的方法

@Override
    public Optional<Long> retrieveUserId(String username) throws SQLException {

        String sql = "SELECT user_id FROM personal_details WHERE username = ?";

        //problem occurs down here
        try (Connection connection = ConnectionPool.getDataSource().getConnection()) {

            //rest of code
    }

任务返回方式:

@Override
    public synchronized Task<AuthenticationStatus> getUserValidationStatus() {

        Task<AuthenticationStatus> loginTask = new Task<>() {
            @Override
            protected AuthenticationStatus call() {

                //rest of code

                Optional<Long> optionalUserID = retrieveUserId(username); //problem
                userID = optionalUserID.orElse(0L);

                //rest of code
        };

        Thread thread = new Thread(loginTask);
        thread.setDaemon(true);
        thread.start();
        return loginTask;
    }

正如您在测试片段中看到的,我尝试初始化JavaFX工具包,以便创建FXApplicationThread,但这没有帮助。
注:执行非测试/源代码时,应用程序运行正常。

fquxozlt

fquxozlt1#

依赖倒置原理

高级类不应该依赖于低级类

**错误示例:**x1c 0d1x

你的OnlineShop强烈依赖于你的CatalogDatabase。这是邪恶的,因为你不能测试你的商店没有一个数据库准备。

好例子:

您的Onlineshop只知道Catalog有一个接口-您现在可以用test-catalog替换database-catalog。甚至还有一个构造函数告诉您选择哪个数据库。
然后呢
当你已经实现了DIP,你将能够用一个测试连接来替换你的连接。你可以提供一个测试连接,它可以做你想做的事情。它甚至可以更进一步,你可以测试坏的情况,以及-你的测试将是独立的,它们运行在哪里。在一个构建服务器上,在你的本地机器上,在......在任何你想要的地方。

摘要

我不知道你在哪里以及如何创建ConnectionPoolDataSourceConnection的示例-但是你必须让它们可替换!(你的代码没有提供它在哪里发生)。
友情提示:不要使用静态方法-它们总是会让你更难(即使它在开始时让一切变得更容易)

相关问题