使用 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.IllegalStateException
:EntityManager
在测试时关闭
当我不使用 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 在测试时关闭)的主要内容,如果未能解决你的问题,请参考以下文章