【问题标题】:Akka and Java 8 TestKit by ExampleAkka 和 Java 8 TestKit 示例
【发布时间】:2018-10-16 17:39:20
【问题描述】:

Java 8 和 Akka 2.12:2.5.16 在这里。我正在尝试利用 Akka TestKit 编写我的第一个(曾经)Akka 单元测试,并且正在努力应用我在网上找到的(极少数)示例中看到的原则。

我的演员:

public class Child extends AbstractActor {
    @Override
    public Receive createReceive() {
        return receiveBuilder()
            .match(Init.class, init -> {
                int workUnit = workService.doSomeWork();
                log.info("Performed work on {}", workUnit);
            }).build();
    }
}

public class Master extends AbstractActor {
    @Inject @Named("CHILD")
    private ActorRef child;

    @Override
    public Receive createReceive() {
        return receiveBuilder()
            .match(Init.class, init -> {
                child.tell(init, self());
            }).build();
    }
}

非常非常简单。所以现在我只想编写一个单元测试来验证当Masteractor 收到Init 消息时,它是否将该消息转发给它的Childactor。迄今为止我最好的尝试:

@RunWith(MockitoJUnitRunner.class)
public class MasterTest {
    private ActorSystem actorSystem;

    @Before
    public void setup() {
        actorSystem = ActorSystem.create("test-system");
    }

    @After
    public void teardown() {
        Duration duration = Duration.create(10L, TimeUnit.SECONDS);
        TestKit.shutdownActorSystem(actorSystem, duration, true);
        actorSystem = null;
    }

    @Test
    public void onInit_shouldSendFordwardToChild() {
        // Given
        TestKit testKit = new TestKit(actorSystem);
        ActorRef master = actorSystem.actorOf(Props.create(Master.class, testKit));

        // When
        master.tell(new Init(), ActorRef.noSender());

        // Then
        testKit.expectMsg(Init.class);
    }
}

当我运行它时,我得到:

java.lang.IllegalArgumentException: no matching constructor found on class com.me.myapp.Master for arguments [class akka.testkit.TestKit]

有人可以帮我将TestKit 实例连接到我的Master 演员,还可以帮我弄清楚如何重构MasterTest 以便它验证我想要完成的事情吗?提前致谢!

【问题讨论】:

    标签: unit-testing java-8 akka akka-testkit


    【解决方案1】:

    我想通了,真不敢相信让这个工作有多么困难:-/

    application.conf:

    MyAkkApp {
      akka {
        remote {
          enabled-transports = ["akka.remote.netty.tcp"]
          netty.tcp {
            hostname = "127.0.0.1"
            port = 2553
          }
        }
      }
    }
    

    然后:

    @RunWith(MockitoJUnitRunner.class)
    public class MasterTest extends TestKit {
        static ActorSystem actorSystem = ActorSystem.create("MyAkkaApp",
            ConfigFactory.load().getConfig("MyAkkaApp"));
    
        static TestProbe child;  // The mock child
        static ActorRef master;
    
        @BeforeClass
        public static void setup() {
            child = new TestProbe(actorSystem, "Child");
            master = actorSystem.actorOf(Props.create(new Creator<Actor>() {
                @Override
                public Actor create() throws Exception {
                    return new Master(child.ref());
                }
            }));
        }
    
        public MasterTest() {
            super(actorSystem);
        }
    
        @Test
        public void onInit_shouldSendFordwardToChild() {
            // Given
            Init init = new Init();
    
            // When
            master.tell(init, super.testActor());
    
            // Then
            child.expectMsg(init);  // Child should have received it
            expectNoMessage();  // Master should not be returning to sender
        }
    }
    

    加油阿卡人!支持产生采用,采用导致标准化,标准化意味着您可以销售 6 位数的企业支持许可证。

    【讨论】:

    • 我不确定您为什么必须对传输配置进行任何更改;我看不到任何远程处理正在进行。除此之外,还有什么问题? Akka 不做依赖注入;当我有父子actor时,我从父级(getContext().actorOf(...))创建了子级,并且为了测试,我将其隔离在它自己的方法中,子类化被测试的actor,并且返回一个测试探针。
    • 感谢@RobCrawford 我希望喜欢看看你的 Akka TestKit 单元测试的一个示例......
    猜你喜欢
    • 2019-12-19
    • 1970-01-01
    • 2015-08-31
    • 2019-12-10
    • 2014-04-18
    • 2021-08-25
    • 1970-01-01
    • 2018-05-08
    • 1970-01-01
    相关资源
    最近更新 更多