在单元测试中,演员如何处理所有消息?

How can await util all messages was processed by actor in unit test?

我在我们的产品中使用 Akka actor。我们写了一些代码:

   @Singleton
   public class SingletonObj {
      private Map<String, Integer> cached = new HashMap();
      public void set(String key, Integer value) {
         cached.put(key, value);
      }

      public void delete(String key){
         cached.delete(key}
      }
   }

   public class MyActor  extends AbstractActor implements InjectedActorSupport {
       @Inject SingletonObj singletonObj;

        public static Props props(Injector injector) {
        return Props.create(MyActor.class, injector);
    }

    public MyActor(Injector injector) {
        this.injector = injector;
        receive(ReceiveBuilder.create()
            .match(AddEvent.class, this::addEvent)
            .match(DeteteEvent.class, this::deleteEvent))
            .build());
        }
        private void addEvent(AddEvent addEvent) {singletonObj.set(addEvent.key, addEvent.value);}

        private void deteleEvent(DeteteEvent event){singletonObj.detele(event.key);}
   }

   public class Controller {

       private Injector injector;
       private ActorSystem actorSystem;

       public void handleAdd()...

       public void handleDelete()...


   }

然后当我在 junit 中为这些 class

编写一些测试时
   @Test public void testMethod(){
       sendAddRequest(...);
       sendDeteleRequest(...)
       ...
       ...

       assertThat(singletonObj.get("someString")).isEqual(42)
    }

那么这个测试是不可靠的,因为当我断言时,所有的事件都没有被处理。

如何等待 actor 系统中的所有事件完成?

导入下面的包,然后你就可以等待,直到你处理完所有的事件,否则测试将在超时后失败。

testCompile 'org.awaitility:awaitility:3.1.0'

import org.awaitility.Awaitility;

在你使用 assertThat 之前

await().pollInterval(5, TimeUnit.MILLISECONDS).until(() -> !isProcessed());

isProcessed 方法如下所示

protected Callable<Boolean> isProcessed() {
        return () -> {
            return singletonObj.getCacheCount()==2;
        };
    }

此致,

维诺斯