【问题标题】:JavaFx MediaPlayer behaves differently in unit test vs application, why?JavaFx MediaPlayer 在单元测试与应用程序中的行为不同,为什么?
【发布时间】:2019-10-10 18:35:21
【问题描述】:

我想从 MP3 文件加载元数据,以由 JavaFx MediaPlayer 播放。这在单元测试中可以正常工作,但在应用程序中却不行。在单元测试中,报告了 6 项元数据,但在应用程序中为零。 “做事”的方法是一样的。

应用程序的主类扩展了Application。测试类从 TestFx 扩展 ApplicationTest。这会影响行为吗?

应用程序:

public class MediaMain extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception {

        Map<String, Object> meta = metaData();

        System.out.printf("Number of meta data: %d.%n", meta.size());
        System.out.println(meta);
    }

    Map<String, Object> metaData() {
        File audioFile = new File("src/main/resources", "beingBoiled.mp3");
        final URI uri = audioFile.toURI();
        final String source = uri.toString();
        Media media = new Media(source);
        new MediaPlayer(media);
        return media.getMetadata();
    }
}

单元测试:

class MediaMainTest extends ApplicationTest {

    @Test
    void testMeta() {
        MediaMain main = new MediaMain();

        Map<String, Object> metaData = main.metaData();

        assertNotEquals(0, metaData.size());
        System.out.printf("Number of meta data: %d.%n", metaData.size());
        System.out.println(metaData);
    }
}

从应用程序打印输出:

Number of meta data: 0.
{}

单元测试的打印输出:

Number of meta data: 6.
{year=1980, artist=The Human League, raw metadata={ID3=java.nio.HeapByteBufferR[pos=254 lim=3214 cap=3214]}, album=Travelogue, genre=(52), title=Being Boiled}

可能是什么原因?这对我来说是个谜。使用 Java 11、JavaFx 11.0.2 和 TestFx 4.0.15-alpha 编写。

【问题讨论】:

  • Media 的元数据是延迟加载的,这意味着它可能不会立即可用。您可以观察元数据,以便在某些属性已知时收到通知。

标签: java javafx testfx


【解决方案1】:

您正在引用位置为 src/main/resources 的文件,这可能不是一个好主意,因为您部署的应用程序可能没有 src/main/resources 目录,而且资源可能捆绑在应用程序 jar 中而不是作为磁盘上的文件,因此使用文件协议访问它是行不通的。

可能最好使用以下内容:

String mediaLoc = getClass().getResource("/beingBoiled.mp3").toExternalForm()
Media media = new Media(mediaLoc)

喜欢How load css file in javafx8。要加载的资源的确切位置可能因构建和项目结构而异。如果您不想从类路径加载,而是通过文件或通过网络 http 调用加载,那么您将需要使用其他东西。

以上代码假设您的构建系统设置为将媒体从src/main/resources 复制到您的目标打包位置,并将资源打包到 jar 文件根目录中的应用程序可分发(例如应用程序 jar 文件)中。

确保您的构建系统实际上正在将文件复制到目标位置。您可以通过运行构建、查看生成的 jar 并运行 jar tvf &lt;myjarfilename&gt;.jar 来检查它是否存在,以查看 mp3 资源是否位于 jar 文件根目录的正确位置。

【讨论】:

  • 最后,我不会从资源文件夹中加载音频文件,这只是一个临时解决方案。如果我以测试方法启动播放器,歌曲将在应用程序和单元测试中播放。但应用程序中仍将不存在元数据。我在 Mac 和 Windows 上的 IntelliJ IDE(最新社区版)中运行。
  • 元数据是一个 ObservableMap,它的内容可能会根据加载的媒体和媒体播放器的状态随着时间而改变。尝试监听地图的变化并记录它们。
  • 当我在两个上下文(Main 类和 MediaMainTest 扩展 ApplicationTest 类)中运行我的测试方法时,我在查询元数据之前测试了延迟(没有改变任何东西),并且还查看了玩家状态。这是不同的;在 MediaMain 应用程序中,即使在播放器启动后它也会报告为 UNKNOWN,而对于单元测试,它会更改为 READY 或 PLAYING,至少在适当的延迟之后。
  • 我确信区别在于 MediaMain 类扩展了 Application 与 MediaMainTest 类中的单元测试扩展了 ApplicationTest 之间的上下文有何不同。但我不明白怎么做。
  • 如果您还没有,请尝试我的建议,add a listener 到元数据的 ObservableMap 并记录其更改。此外,source code in the media package Javadoc 包括使用 Media 的综合日志记录和异常报告信息。请实施所有这些并检查日志。
猜你喜欢
  • 2018-12-15
  • 2020-07-26
  • 1970-01-01
  • 2020-04-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-20
  • 1970-01-01
相关资源
最近更新 更多