ses*_*ses 12 java scala mocking actor akka
我很想知道如何通过在Actor中模拟一些方法(用模拟的替换真实对象/ actor的方法实现)来测试Akka Actor功能.
我用akka.testkit.TestActorRef;
另外:我试图使用,SpyingProducer但目前尚不清楚如何使用它.(就像我,如果我在其实现中创建了actor,它将与我现在一样).谷歌搜索结果不是很详细.
我用powemockito和java.但是这没关系.我很想知道how to do it in principle 任何语言与任何框架
(所以如果你不知道power/mockito如何工作只是提供你的代码..(请)或完全了解你将如何使用你知道的工具.)
所以,假设我们有一个要测试的Actor:
package example.formock;
import akka.actor.UntypedActor;
public class ToBeTestedActor extends UntypedActor {
@Override
public void onReceive(Object message) throws Exception {
if (message instanceof String) {
getSender().tell( getHelloMessage((String) message), getSelf());
}
}
String getHelloMessage(String initMessage) { // this was created for test purposes (for testing mocking/spy capabilities). Look at the test
return "Hello, " + initMessage;
}
}
Run Code Online (Sandbox Code Playgroud)
在我们的测试中,我们想要替换getHelloMessage()其他东西.
这是我的尝试:
package example.formock;
import akka.testkit.TestActorRef;
...
@RunWith(PowerMockRunner.class)
@PrepareForTest(ToBeTestedActor.class)
public class ToBeTestedActorTest {
static final Timeout timeout = new Timeout(Duration.create(5, "seconds"));
@Test
public void getHelloMessage() {
final ActorSystem system = ActorSystem.create("system");
// given
final TestActorRef<ToBeTestedActor> actorRef = TestActorRef.create(
system,
Props.create(ToBeTestedActor.class),
"toBeTestedActor");
// First try:
ToBeTestedActor actorSpy = PowerMockito.spy(actorRef.underlyingActor());
// change functionality
PowerMockito.when(actorSpy.getHelloMessage (anyString())).thenReturn("nothing"); // <- expecting result
try {
// when
Future<Object> future = Patterns.ask(actorRef, "Bob", timeout);
// then
assertTrue(future.isCompleted());
// when
String resultMessage = (String) Await.result(future, Duration.Zero());
// then
assertEquals("nothing", resultMessage); // FAIL HERE
} catch (Exception e) {
fail("ops");
}
}
}
Run Code Online (Sandbox Code Playgroud)
结果:
org.junit.ComparisonFailure:
Expected :nothing
Actual :Hello, Bob
Run Code Online (Sandbox Code Playgroud)
小智 10
Akka有一个类AutoPilot,它基本上是演员的一般模拟,具有响应消息和断言消息被发送的能力.
http://doc.akka.io/docs/akka/snapshot/java/testing.html
这是该页面的java示例.您可以创建一个探测器,设置一个可以响应消息的自动驾驶仪,并从中获取一个ActorRef可以代替您真实演员的消息.
new JavaTestKit(system) {{
final JavaTestKit probe = new JavaTestKit(system);
// install auto-pilot
probe.setAutoPilot(new TestActor.AutoPilot() {
public AutoPilot run(ActorRef sender, Object msg) {
sender.tell(msg, ActorRef.noSender());
return noAutoPilot();
}
});
// first one is replied to directly ...
probe.getRef().tell("hello", getRef());
expectMsgEquals("hello");
// ... but then the auto-pilot switched itself off
probe.getRef().tell("world", getRef());
expectNoMsg();
}};
Run Code Online (Sandbox Code Playgroud)
所以我可能不理解这个问题,但你可能不想嘲笑演员,因为嘲笑的目的是用具有调用期望的测试副本替换诸如 dao 之类的东西 - actor 并不真正符合要求因为它是您扩展的东西而不是依赖项 - 模拟实际上只适用于真正的依赖项。
TestActorRef 专门为您提供了对底层 Actor 的访问 - 在大多数正常情况下,您只能向 Actor 发送消息,而不能直接调用其上的任何内容。TestActoRef 通过允许您访问您真正的 Actor 扩展而不仅仅是您只能访问的 ActorRef 来消除此限制!或者 ?反对(发送或询问)。
我是一名 Scala 开发人员,所以我的见解希望是不可知的。我具体不知道java api,但这应该不重要。
我的建议是通过 actor ref 获取真实的 Actor 对象,然后测试该方法或找出某种方法通过真实消息获取测试覆盖率。