我想从 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 编写。
最佳答案
您正在引用位置为 src/main/resources
的文件,这可能不是一个好主意,因为您部署的应用程序可能不会有 src/main/resources
目录,加上资源可能捆绑在应用程序 jar 中,而不是作为磁盘上的文件,因此使用文件协议(protocol)访问它是行不通的。
最好使用如下所示的内容:
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 <myjarfilename>.jar
来检查它是否存在。查看 mp3 资源是否位于 jar 文件根目录的正确位置。
关于JavaFx MediaPlayer 在单元测试与应用程序中的行为不同,为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58329133/