【问题标题】:TestKit unit test failure for AbstractPersistentActorWithAtLeastOnceDelivery actor created with TestActorRef使用 TestActorRef 创建的 AbstractPersistentActorWithAtLeastOnceDelivery 演员的 TestKit 单元测试失败
【发布时间】:2018-03-20 18:22:32
【问题描述】:

我正在尝试为我的一个演员编写单元测试,该演员使用 TestKit 从 AbstractPersistentActorWithAtLeastOnceDelivery 派生。我需要使用 TestActorRef.create(...) 创建一个actor,因为我需要获取一个底层Actor 以便将模拟注入到actor的实现中。

我的(简化的)演员

public class MyActor extends AbstractPersistentActorWithAtLeastOnceDelivery {

@Override
public Receive createReceive() {
    return receiveBuilder().match(String.class, message -> {
        persist(new MessageSent(message), event -> updateState(event));
    }).match(ConfirmMessage.class, confirm -> {
        persist(new MessageConfirmed(confirm.deliveryId), event -> 
         updateState(event));
    }).matchAny(message -> log.info("Received unexpected message of class {}. 
     Content: {}", message.getClass().getName(), message.toString())).build();

}

 void updateState(Object received) {
    if (received instanceof MessageSent) {
        final MessageSent messageSent = (MessageSent) received;
        ActorRef destinationActor = 
        findDestinationActor(messageSent.messageData);               
        deliver(actorSystem.actorSelection(destinationActor.path()), 
    deliveryId -> new Message(deliveryId, messageSent.messageData));
    } else if (received instanceof MessageConfirmed) {
        final MessageConfirmed messageConfirmed = (MessageConfirmed) received;
        confirmDelivery(messageConfirmed.deliveryId);
    }
}

单元测试:

@Test
public void actorTest() {
  ActorSystem system = ActorSystem.create();
  TestKit probe = new TestKit(system);
  TestActorRef<myActor> testActor = TestActorRef.create(system, props, 
     probe.getRef());
  MyActor myActor = testActor.underlyingActor();
  injectMocks(myActor); // my method
  testActor.tell("testMessage", probe.getRef());
  List<Object> receivedMessages = probe.receiveN(1, FiniteDuration.create(3, 
    TimeUnit.SECONDS));

}

在调试器中,我看到 updateState() 中的 Deliver() 方法被调用,但单元测试失败并出现错误:

断言失败:等待 1 条消息(得到 0)时超时(3 秒)

我想知道是否可以使用 TestKit 来测试通过 TestActorRef 创建的演员,以及我的演员扩展 AbstractPersistentActorWithAtLeastOnceDelivery 的事实是否与测试失败有关

【问题讨论】:

    标签: java akka akka-testkit


    【解决方案1】:

    不能将TestActorRef 与 Akka 持久性一起使用。它有时会起作用,但通常会以您在问题中描述的方式失败。 TestKit 的其他特性与 Akka 持久性配合得很好。

    查看https://doc.akka.io/docs/akka/current/testing.html#synchronous-testing-testactorref下的警告:

    警告

    由于 TestActorRef 的同步特性,它不适用于 Akka 提供的一些支持特性,因为它们需要异步行为才能正常运行。 Akka Persistence 提供的 PersistentActor 和 AtLeastOnceDelivery 不能很好地与测试 actor 参考混合的特征示例。

    【讨论】:

    • 这是否意味着无法对使用依赖注入的持久性参与者进行单元测试?需要访问 Actor 类实例来注入模拟或真正的依赖项,并且只能通过 TestActorRef 来完成
    • 您可以通过使用class MyActorUnderTest extends MyActor 之类的东西进行测试来解决这个问题,您可以在创建演员之前在其中设置模拟
    猜你喜欢
    • 1970-01-01
    • 2021-02-11
    • 1970-01-01
    • 2010-10-03
    • 2015-10-25
    • 1970-01-01
    • 1970-01-01
    • 2021-12-06
    • 1970-01-01
    相关资源
    最近更新 更多