使用 JPA.withTransaction 的测试 Actor(java.lang.IllegalStateException:EntityManager 在测试时关闭)

Posted

技术标签:

【中文标题】使用 JPA.withTransaction 的测试 Actor(java.lang.IllegalStateException:EntityManager 在测试时关闭)【英文标题】:Test Actor which use JPA.withTransaction (java.lang.IllegalStateException: EntityManager is closed when tested) 【发布时间】:2015-04-24 10:47:48 【问题描述】:

我已经编写了一个基于 WebSocket 的 Actor,它工作正常,但我需要测试。

我已经用 Next 方式创建了 WebSocket:

public static WebSocket<JsonNode> bulkEventsImportWebSocket() 
   return WebSocket.withActor(EventsImportActor::props);

我的演员是下一个:

public class EventsImportActor extends UntypedActor 

   public static final Injector INJECTOR = Guice.createInjector(new DefaultModule());

   private static ObjectMapper mapper = INJECTOR.getInstance(ObjectMapper.class);

   public static Props props(ActorRef out) 
      Logger.info("EventsImportActor created");
      return Props.create(EventsImportActor.class, out);
   

   private final ActorRef out;

   public EventsImportActor(ActorRef out) 
      this.out = out;
   

   @Override
   public void onReceive(Object message) throws Exception 
      Logger.info("EventsImportActor received message");
/*
      self().tell(PoisonPill.getInstance(), self());
*/
      try 

         JsonNode content = (JsonNode) message;

         JPA.withTransaction(() -> 
            someHugeImportOperationWithJPA(content)
         );
         Logger.info("EventsImportActor  message processed");
       catch (Throwable e) 
         out.tell(ControllerUtils.getErrosObjectNode(e, mapper), self());
      
   

我已经写了下一个测试:

public class EventsImportActorTest extends WithServer 


   public static final Injector INJECTOR = Guice.createInjector(new DefaultModule());
   private static ObjectMapper mapper = INJECTOR.getInstance(ObjectMapper.class);

   static ActorSystem system;


   @BeforeClass
   public static void setUp()
      system = ActorSystem.create();
      Logger.info("setUp done");
   

   @AfterClass
   public static void stopApp() 
      system.shutdown();
   


 @Test
   public void bulkEventsImportWebSocketTest() throws Throwable 


      Props propsTest = Props.create(EventsImportTestActor.class);
      final ActorRef testActorRef = system.actorOf(propsTest);

      Props propsImport = EventsImportActor.props(testActorRef);
      ActorRef importActorRef = system.actorOf(propsImport);

      importActorRef.tell(mapper.readTree(""), testActorRef);

   


我的 EventsImportTestActor 会做出断言,现在看起来像这样:

public class EventsImportTestActor extends UntypedActor 
   @Override
   public void onReceive(Object message) throws Exception 
      Logger.info("received by EventsImportTestActor message: " + message);
   

当我运行这个测试时,我收到java.lang.IllegalStateExceptionEntityManager 在测试时关闭 当我不使用 JPA 时,它可以正常工作。

我应该如何更改我的测试以授予演员访问数据库的权限(对 EntityManager 的有效访问)?

【问题讨论】:

【参考方案1】:

将测试更改为下一个

` @Test public void bulkEventsImportWebSocketTest() throws Throwable

    Props propsTest = Props.create(EventsImportTestActor.class);
    final ActorRef testActorRef = system.actorOf(propsTest);

    EventJsonDataFormat format = new EventJsonDataFormat(mapper, occurrenceDAO);
    JsonNode content = mapper.readTree("");

    Logger.info("content: " + content);
    JPA.withTransaction(() -> 
        EventsImportActor.bulkImport(format.importFromJson(content), testActorRef, testActorRef);
    );

`

并通过传递 self() ref 将 bulkImport 方法转换为静态

bulkImport(format.importFromJson(content), out, this.self());

【讨论】:

以上是关于使用 JPA.withTransaction 的测试 Actor(java.lang.IllegalStateException:EntityManager 在测试时关闭)的主要内容,如果未能解决你的问题,请参考以下文章

python中的测地距离变换

模仿某站的测导航自己加以整理

数据结构-编程实现一个单链表的测长

AB-web服务的测压工具

win7 / mysql-8.0.11-winx64 安装的测坑步骤

数据结构-编程实现一个双链表的建立,双链表的打印,双链表的测长