我正试图使用Testkit使用以下代码设置一个简单的Akka测试:
import akka.actor.typed.ActorRef;
import akka.actor.typed.Behavior;
import akka.actor.typed.Scheduler;
import akka.actor.typed.javadsl.AskPattern;
import akka.actor.typed.javadsl.Behaviors;
// #test-header
//import akka.actor.testkit.typed.javadsl.*;
import akka.actor.testkit.typed.javadsl.TestInbox;
// #test-header
import akka.actor.testkit.typed.javadsl.TestProbe;
import org.junit.AfterClass;
import org.junit.Test;
import org.scalatestplus.junit.JUnitSuite;
import java.time.Duration;
import java.util.concurrent.CompletionStage;
import java.util.stream.IntStream;
import java.util.Objects;
import static org.junit.Assert.assertEquals;
// #test-header
public class AsyncTestingExampleTest
// #test-header
extends JUnitSuite
// #test-header
{
static final ActorTestKit testKit = ActorTestKit.create();
// #test-header
// #under-test
public static class Echo {
public static class Ping {
public final String message;
public final ActorRef<Pong> replyTo;
public Ping(String message, ActorRef<Pong> replyTo) {
this.message = message;
this.replyTo = replyTo;
}
}
public static class Pong {
public final String message;
public Pong(String message) {
this.message = message;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Pong)) return false;
Pong pong = (Pong) o;
return message.equals(pong.message);
}
@Override
public int hashCode() {
return Objects.hash(message);
}
}
public static Behavior<Ping> create() {
return Behaviors.receive(Ping.class)
.onMessage(
Ping.class,
ping -> {
ping.replyTo.tell(new Pong(ping.message));
return Behaviors.same();
})
.build();
}
}
// #under-test
// #under-test-2
static class Message {
int i;
ActorRef<Integer> replyTo;
Message(int i, ActorRef<Integer> replyTo) {
this.i = i;
this.replyTo = replyTo;
}
}
public static class Producer {
private Scheduler scheduler;
private ActorRef<Message> publisher;
Producer(Scheduler scheduler, ActorRef<Message> publisher) {
this.scheduler = scheduler;
this.publisher = publisher;
}
public void produce(int messages) {
IntStream.range(0, messages).forEach(this::publish);
}
private CompletionStage<Integer> publish(int i) {
return AskPattern.ask(
publisher,
(ActorRef<Integer> ref) -> new Message(i, ref),
Duration.ofSeconds(3),
scheduler);
}
}
// #under-test-2
// #test-shutdown
@AfterClass
public static void cleanup() {
testKit.shutdownTestKit();
}
// #test-shutdown
@Test
public void testVerifyingAResponse() {
// #test-spawn
ActorRef<Echo.Ping> pinger = testKit.spawn(Echo.create(), "ping");
TestProbe<Echo.Pong> probe = testKit.createTestProbe();
pinger.tell(new Echo.Ping("hello", probe.ref()));
probe.expectMessage(new Echo.Pong("hello"));
// #test-spawn
}
@Test
public void testVerifyingAResponseAnonymous() {
// #test-spawn-anonymous
ActorRef<Echo.Ping> pinger = testKit.spawn(Echo.create());
// #test-spawn-anonymous
TestProbe<Echo.Pong> probe = testKit.createTestProbe();
pinger.tell(new Echo.Ping("hello", probe.ref()));
probe.expectMessage(new Echo.Pong("hello"));
}
@Test
public void testStoppingActors() {
TestProbe<Echo.Pong> probe = testKit.createTestProbe();
// #test-stop-actors
ActorRef<Echo.Ping> pinger1 = testKit.spawn(Echo.create(), "pinger");
pinger1.tell(new Echo.Ping("hello", probe.ref()));
probe.expectMessage(new Echo.Pong("hello"));
testKit.stop(pinger1);
// Immediately creating an actor with the same name
ActorRef<Echo.Ping> pinger2 = testKit.spawn(Echo.create(), "pinger");
pinger2.tell(new Echo.Ping("hello", probe.ref()));
probe.expectMessage(new Echo.Pong("hello"));
testKit.stop(pinger2, Duration.ofSeconds(10));
// #test-stop-actors
}
@Test
public void testObserveMockedBehavior() {
// #test-observe-mocked-behavior
// simulate the happy path
Behavior<Message> mockedBehavior =
Behaviors.receiveMessage(
message -> {
message.replyTo.tell(message.i);
return Behaviors.same();
});
TestProbe<Message> probe = testKit.createTestProbe();
ActorRef<Message> mockedPublisher =
testKit.spawn(Behaviors.monitor(Message.class, probe.ref(), mockedBehavior));
// test our component
Producer producer = new Producer(testKit.scheduler(), mockedPublisher);
int messages = 3;
producer.produce(messages);
// verify expected behavior
IntStream.range(0, messages)
.forEach(
i -> {
Message msg = probe.expectMessageClass(Message.class);
assertEquals(i, msg.i);
});
// #test-observe-mocked-behavior
}
@Test
public void systemNameShouldComeFromTestClass() {
assertEquals(testKit.system().name(), "AsyncTestingExampleTest");
}
// #test-header
}
// #test-header
此代码基于:https://doc.akka.io/docs/akka/current/typed/testing-async.html#configuration
相关代码的依赖pom.xml是:
它使用来自https://doc.akka.io/docs/akka/current/typed/testing-async.html#configuration
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<scala.binary.version>2.13</scala.binary.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.typesafe.akka</groupId>
<artifactId>akka-bom_${scala.binary.version}</artifactId>
<version>2.6.14</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>com.typesafe.akka</groupId>
<artifactId>akka-stream_2.13</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.3.3</version>
</dependency>
<dependency>
<groupId>com.typesafe.akka</groupId>
<artifactId>akka-actor-typed_${scala.binary.version}</artifactId>
</dependency>
<dependency>
<groupId>com.typesafe.akka</groupId>
<artifactId>akka-actor-testkit-typed_${scala.binary.version}</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
问题是编译器找不到一些导入的类,例如:
import akka.actor.testkit.typed.javadsl.TestInbox;
// #test-header
import akka.actor.testkit.typed.javadsl.TestProbe;
import org.junit.AfterClass;
import org.junit.Test;
import org.scalatestplus.junit.JUnitSuite
并且由于错误而失败";无法解析符号";对于上述每个类别。
我已经尝试清除我的Maven依赖项,但似乎我没有正确设置依赖项。
使用Akka Typed Testkit for Java是否需要其他依赖项?
现在答案很明显了。我忽略了这样一个事实,即我是从非测试目录执行测试代码的,由于测试依赖关系的范围是测试,所以这些库不可用。此外,我在这里的答案是";睡在上面";。