playframework-2.0 - 当存在多个测试用例时 Play 2.0 Akka 系统关闭

标签 playframework-2.0 akka

我有两个 Controller ,它们都在 Play 2.0 中使用 AKKA Actor 。因此,有两个测试用例针对这两个 API 进行测试。然而,当执行'play test'时,只有一个测试用例会成功,另一个失败。如果我单独运行它们,它会成功运行。我的预感是 Actor 系统在第一次测试时就被关闭了。但是,我是 Play 2 和 Akka 的新手,这只是我的猜测。有解决方法吗?

@Test
public void callPostA() {
running(testServer(2222, fakeApplication(inMemoryDatabase())), new Runnable() {
        @Override
        public void run() {
            HttpPost httpPost = new HttpPost("http://localhost:2222/controllera");
            ....
        }
    });
}
@Test
public void callPostB() {
running(testServer(2222, fakeApplication(inMemoryDatabase())), new Runnable() {
        @Override
        public void run() {
            HttpPost httpPost = new HttpPost("http://localhost:2222/controllerb");
            ....
        }
    });
}

两个 Controller 如下:
public class PostA extends Controller {
    // master actor for workers
    public static ActorRef masterActorA = Akka.system().actorOf(new Props(new UntypedActorFactory() {
    public UntypedActor create() {
          return new PostAActorMaster(Config.NUMBER_OF_WORKER_ACTOR);
       }
        }), "PostAActorMaster");

    public static Result postA() {

        Map<String, String[]> dict = body.asFormUrlEncoded();
        String paramField1 = dict.get("paramField1");
        String paramField2 = dict.get("paramField2");

        ProductInfo pInfo = new ProductInfo(paramField1, paramField2);
        ProductMessage pMessage = new ProductMessage(pInfo);
        return async(
        Akka.asPromise(ask(masterActorA, pMessage, 15000)).map(
            new Function<Object, Result>() {
                        ...
                        }
                ));
}

public class PostB extends Controller {
    // master actor for workers
    public static ActorRef masterActorB = Akka.system().actorOf(new Props(new UntypedActorFactory() {
    public UntypedActor create() {
          return new PostBActorMaster(Config.NUMBER_OF_WORKER_ACTOR);
       }
        }), "PostBActorMaster");

    public static Result postB() {

        Map<String, String[]> dict = body.asFormUrlEncoded();
        String paramField3 = dict.get("paramField3");
        String paramField4 = dict.get("paramField4");

        BillInfo bInfo = new BillInfo(paramField3, paramField4);
        BillMessage pMessage = new BillMessage(bInfo);
        return async(
        Akka.asPromise(ask(masterActorB, pMessage, 15000)).map(
            new Function<Object, Result>() {
                        ...
                        }
                ));
}

PostA的AKKA Master和worker:
public class PostAActorMaster extends UntypedActor {

    private final ActorRef workerRouter;

    public PostAActorMaster(final int nrOfWorkers) {
        workerRouter = this.getContext().actorOf(new Props(PostAActorMaster.class).withRouter(new RoundRobinRouter(nrOfWorkers)));
    }

    public void onReceive(Object messageObj) {
           try {
            if (messageObj instanceof ProductMessage) {
               // invoke worker to submit channel messaages
               workerRouter.tell(messageObj, getSender());
                } else if (messageObj instanceof ProductMessageResult) {
                    ......
                    getSender().tell("OK");
                }
            } catch (Exception e) {
                ......
            } 
    }

}


public class PostAActorWorker extends UntypedActor {
    public void onReceive(Object messageObj) throws Exception {
              if (messageObj instanceof ProductMessage) {
                     ProductMessage pMessage = (ProductMessage)messageObj;
                     ProductInfo pInfo = pMessage.getProductInfo();
                     log.info(pInfo.getProductId());
                     ProductMessageResult pr = new ProductMessageResult(pInfo);
                 PostA.masterActor.tell(pr, getSender());
              }
        }
}

管理对象:
public class ProductInfo extends Model {
        @Id
        private String productId;
        ...
   }

最佳答案

我看不到问题了。这是我的测试用例的结构。也许你可以尝试一下,看看它是否适合你。

斯卡拉:

object LoginApiTest extends PlaySpecification {
  "login api quick login" should {
    "post login data" in new WithCleanTestData {
      var org1 = new OrgInfo("testorg", "Test Inc");
      org1.save();
    }
  }
}


abstract class WithCleanTestData extends WithApplication(FakeApplication(
  additionalConfiguration = TestConf.getConf.toMap
  )) {
  override def around[T: AsResult](t: => T): Result = super.around {
    prepareDbWithData()
    t
  }
  def prepareDbWithData() = {
      OrgInfo.getAllOrgInfo.foreach(_.delete)
  }
}

java :
public class MyHelpers extends Helpers {
    public static FakeApplication myFakeApplication(Map<String,String> additionalConfiguration) {
        List<String> withoutPlugins = new ArrayList<String>();
        List<String> additionalPlugins = new ArrayList<String>();
        return new MyFakeApplication(new java.io.File("."), MyHelpers.class.getClassLoader(),
            additionalConfiguration, withoutPlugins, additionalPlugins, null);
    }
}

public class BaseModelTest extends WithApplication {
    @Before
    public void before() {
    }
}

public class PostTest extends BaseModelTest {

    @Test
    public void test1() {
    }
}

此外,您可以尝试将此设置添加到 Build.scala 中:
parallelExecution in Test := false

关于playframework-2.0 - 当存在多个测试用例时 Play 2.0 Akka 系统关闭,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11090681/

相关文章:

java - 一个 Java Play 操作中的多个 WS 调用

scala - 有条件地组合枚举

playframework - routesImport 在 playframework 中不起作用

scala - 玩 ! 2.2.4/Akka : tests failed when run together, 但分开没问题

scala - 一次带有文件上传extractRequestContext和案例类的Akka HTTP API服务?

java - 非并发环境下Akka框架的使用

multithreading - akka actor 如何在底层线程上实现?

docker - 将 Play 应用程序构建为 Docker 镜像,重新映射端口

scala - 有没有办法根据 Akka(Scala) 中的存储大小来路由消息

java - 在 jquery forntier 日历中加载文件时出错