简体   繁体   中英

How to unit test a method returning Uni/Multi of Smallrye mutiny reactive library?

I am using Smallrye Mutiniy reactive library in my Quarks application as it is supported natively in Quarks applications.

I'am trying to write unit tests for a service class. I am not sure how to write unit tests for a method that returns Uni / Multi .

A method returning Uni<String>

public Uni<String> hello(final String name) {
    final String message = "Hello " + name;
    return Uni.createFrom().item(message);
}

Unit implemented for the above method

@Test
void testHello() {
    final Uni<String> casePass = hello("Ram");
    // assertion passes and all good with this.
    casePass.subscribe().with(message -> Assertions.assertEquals("Hello Ram", message));
    
    final Uni<String> caseFail = hello("Ravan");
    //  It is expected to fail the assertion, and it does. But the test is not failing, instead aseertion fail message simply logged to the console.
    caseFail.subscribe().with(message -> Assertions.assertEquals("Hello Sita", message));
}

Console logs

[-- Mutiny had to drop the following exception --]
Exception received by: io.smallrye.mutiny.helpers.UniCallbackSubscriber.onItem(UniCallbackSubscriber.java:71)
org.opentest4j.AssertionFailedError: expected: <Hello Sita> but was: <Hello Ram>
    at org.junit.jupiter.api.AssertionUtils.fail(AssertionUtils.java:55)
    at org.junit.jupiter.api.AssertionUtils.failNotEqual(AssertionUtils.java:62)
    at org.junit.jupiter.api.AssertEquals.assertEquals(AssertEquals.java:182)
    at org.junit.jupiter.api.AssertEquals.assertEquals(AssertEquals.java:177)
    at org.junit.jupiter.api.Assertions.assertEquals(Assertions.java:1124)
...

There are several approaches. You can use the utility methods provided in smallrye.io/smallrye-mutiny/guides/testing. However, if, according to your comment, you need more, I would recommend the following approach:

final Uni<Greeting> casePass = hello("Ram");
Greeting g = casePAss.await().atMost(Duration.ofSeconds(5)); // To be sure we don't stay tucked
// Assertions come here

So basically, you block until the item is sent. Avoid await().indefinitely() because it may block your test if the Uni never send an item. Not that await()... throws an exception if the Uni sends a failure.

I would really recommend using the way of testing from SmallRey.

https://smallrye.io/smallrye-mutiny/guides/testing

You still can get the object out of the multi/uni use invoke, for example.

 public static Uni<String> hello(final String name) {
    final String message = "Hello " + name;
    return Uni.createFrom().item(message);
}

@Test
public void testUnit() {
    UniAssertSubscriber<String> tester = hello("someone")
            .invoke( i -> Assertions.assertEquals("Hello someone", i))
            .invoke(i -> Assertions.assertNotNull(i))
            .subscribe().withSubscriber(UniAssertSubscriber.create());
    tester.assertCompleted();
}

@Test
public void secondUnit() {
    UniAssertSubscriber<String> tester = hello("none")
            .invoke( i -> Assertions.assertEquals("Hello someone", i))
            .invoke(i -> Assertions.assertNotNull(i))
            .subscribe().withSubscriber(UniAssertSubscriber.create());
    tester.assertCompleted();
}

I hope you can use it like that

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