2012-06-18 4 views
6

Ich habe zwei Controller, die beide AKKA-Akteure in Play 2.0 verwenden. Dementsprechend gibt es zwei Testfälle, die diese beiden APIs testen. Wenn Sie jedoch "Test abspielen" ausführen, wird nur einer der Testfälle erfolgreich ausgeführt, der andere schlägt fehl. Wenn ich sie separat ausführe, wird es erfolgreich ausgeführt. Meine Ahnung ist, dass das Aktorsystem beim ersten Test abgeschaltet wurde. Ich bin jedoch neu bei Play 2 und Akka, das ist nur meine Vermutung. Gibt es eine Problemumgehung?Play 2.0 Akka-System herunterfahren, wenn mehrere Testfälle vorhanden sind

@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"); 
      .... 
     } 
    }); 
} 

zwei Regler sind wie folgt:

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 Meister und Arbeiter:

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()); 
       } 
     } 
} 

Managed Object:

public class ProductInfo extends Model { 
     @Id 
     private String productId; 
     ... 
    } 
+0

Haben Sie eine Lösung gefunden? Ich habe das gleiche Problem in 2.2.4 – Isammoc

+0

Ähnliche ähnliche Ausgaben - 2.3 akka spring mit dem play2 actor-System. – JasonG

+0

[Fehler] sbt.ForkMain $ ForkError: Fehler beim Erstellen von Bean mit dem Namen 'accountServiceController' definiert in der Datei [/Users/admin/Development/src/totes/app/target/scala-2.11/classes/controllers/AccountServiceController.class]: Instanziierung von Bean fehlgeschlagen; verschachtelte Ausnahme ist org.springframework.beans.BeanInstantiationException: Bean-Klasse konnte nicht instanziiert werden [controllers.AccountServiceController]: Konstruktor hat Ausnahme ausgelöst; verschachtelte Ausnahme ist java.lang.IllegalStateException: kann keine Kinder beim Beenden oder Beenden erstellen – JasonG

Antwort

1

Ich sehe nicht das Problem nicht mehr. Hier ist die Struktur meines Testfalls. Vielleicht kannst du es ausprobieren und sehen, ob es für dich funktioniert.

Scala:

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() { 
    } 
} 

Auch können Sie diese Einstellung auf Ihre Build.scala versuchen hinzuzufügen:

parallelExecution in Test := false 
0

Hey, ich wurde mit einem statischen ActorSystem und das verursachte ein Problem

[error] sbt.ForkMain$ForkError: Error creating bean with name 'accountServiceController' defined in file [/Users/admin/Development/src/totes/app/target/scala-2.11/classes/controllers/Ac‌​countServiceController.class]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [controllers.AccountServiceController]: Constructor threw exception; nested exception is java.lang.IllegalStateException: cannot create children while terminating or terminated 

Durch ein dynamisches ActorSystem, das bei jedem Start der App erstellt wird, scheint das Problem zu verschwinden. Ich habe eine Weile daran gearbeitet, also wollte ich dies hier als mögliche Lösung veröffentlichen.

+0

Antwort von hier geposteten Entwicklern http://stackoverflow.com/a/20893193/1996639 – zella