简体   繁体   中英

JavaFx MediaPlayer behaves differently in unit test vs application, why?

I want to load meta data from an MP3 file, to be played by a JavaFx MediaPlayer. This works fine in the unit test, but not in the application. In the unit test, 6 items of metaData reported, but zero in the application. The method that "does the work" is the same.

The main class of the application extends Application. The test class extends ApplicationTest from TestFx. Could that affect the behavior?

The application:

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();
    }
}

The unit test:

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);
    }
}

Printout from the application:

Number of meta data: 0.
{}

Printout from the unit test:

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}

What could be the reason? It's a mystery to me. Written with Java 11, JavaFx 11.0.2 and TestFx 4.0.15-alpha.

You are referencing a file with a location of src/main/resources , this is probably not a good idea as your deployed application likely won't have a src/main/resources directory, plus the resource might be bundled within the application jar rather than as a file on disk, so using a file protocol to access it won't work.

It is probably best to use something like below:

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

Like in How load css file in javafx8 . The exact location of the resource to be loaded may differ based on build and project structure. If you don't want to load from the class path, but instead via a File or over network http call, then you would need to use something else.

The above code assumes that your build system is setup to copy the media from the src/main/resources to your target packaging location and package the resource into the application distributable (eg an application jar file) in the root of the jar file.

Make sure that your build system is actually copying the file to the target location. You can check if it is there by running your build, looking at the resultant jar and running jar tvf <myjarfilename>.jar to see if the mp3 resource is in the correct location at the root of the jar file.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM