控制器测试 - CacheManager已关闭。它已无法再使用

时间:2016-03-06 22:30:07

标签: java playframework guice

我在尝试使用Play framework 2.4.6Guice中进行控制器测试时,会遇到标题错误。它与Controller中的任何view.render代码一起出现。 redirect不会产生此问题。

堆栈:

1) Error in custom provider, java.lang.IllegalStateException: The CacheManager has been shut down. It can no longer be used.
  at play.api.cache.EhCacheModule.play$api$cache$EhCacheModule$$bindCache$1(Cache.scala:178):
Binding(interface net.sf.ehcache.Ehcache qualified with QualifierInstance(@play.cache.NamedCache(value=play)) to ProviderTarget(play.api.cache.NamedEhCacheProvider@4c8f1e9)) (via modules: com.google.inject.util.Modules$OverrideModule -> play.api.inject.guice.GuiceableModuleConversions$$anon$1)
  while locating net.sf.ehcache.Ehcache annotated with @play.cache.NamedCache(value=play)
  at play.api.cache.EhCacheModule.play$api$cache$EhCacheModule$$bindCache$1(Cache.scala:179):
Binding(interface play.api.cache.CacheApi qualified with QualifierInstance(@play.cache.NamedCache(value=play)) to ProviderTarget(play.api.cache.NamedCacheApiProvider@38fd7da7)) (via modules: com.google.inject.util.Modules$OverrideModule -> play.api.inject.guice.GuiceableModuleConversions$$anon$1)
  while locating play.api.cache.CacheApi annotated with @play.cache.NamedCache(value=play)
  while locating play.api.cache.CacheApi
    for parameter 0 at play.cache.DefaultCacheApi.<init>(DefaultCacheApi.java:20)
  at play.cache.DefaultCacheApi.class(DefaultCacheApi.java:20)
  while locating play.cache.DefaultCacheApi
  while locating play.cache.CacheApi 

以下是我的设置:

控制器:

@Singleton
public class AccountController extends Controller {
  private AccountService accountService;

  @Inject
  public Controller(AccountService a) {
      accountService = a;
  }

  public Result addAccount() {
     boolean success = accountService.addAccount();
     if (success) 
       return ok(CreateAccount.render());//<--THIS TRIGGERS THE ERROR WHEN RUNNING THE TEST
  }
}

接口:

@ImplementedBy(AccountServiceImpl.class)
public interface AccountService {
   boolean addAccount();
}

实现:

public class AccountServiceImpl implements AccountService {
   @Override
   public boolean addAccount() {
   }
}

测试:

public class TestClass {
@Inject
Application application;

final AccountService accountServiceMock = mock(AccountService.class);

@Before
public void setup() {
    Module testModule = new AbstractModule() {
        @Override
        public void configure() {
            bind(AccountService.class).toInstance(accountServiceMock);
        }
    };

    GuiceApplicationBuilder builder = new GuiceApplicationLoader()
            .builder(new ApplicationLoader.Context(Environment.simple()))
            .overrides(testModule);
    Guice.createInjector(builder.applicationModule()).injectMembers(this);

    Helpers.start(application);
}

@Test
public void testMethod() throws Exception {
    RequestBuilder request = new RequestBuilder()
            .session("userId", "1")
            .uri(controllers.routes.AccountController.addAccount().url());

    running(application, () -> {
        when(accountServiceMock.addAccount().thenReturn(true);
        assertEquals(OK, route(request).status());
    });

}

任何帮助表示赞赏!

编辑:我已经找到导致问题的确切原因,但我仍然不知道原因。

RequestBuilder request = new RequestBuilder()
            .session("userId", "1") // <--- THIS IS CAUSING THE PROBLEM
            .uri(controllers.routes.AccountController.addAccount().url());

更确切地说:

"userId" // <--- THIS. userIds, or any other I've tried, solved the issue.

要重新恢复,只要在测试方法中为userId设置RequestBuilder会话以及在控制器中设置view.render,就会发生此错误。

无论我是在html中使用这样的会话,还是在控制器中使用。谁知道这里发生了什么?

1 个答案:

答案 0 :(得分:0)

将测试方法中的所有内容移至running调用内:

running(application, () -> {
    RequestBuilder request = new RequestBuilder()
        .session("userId", "1")
        .uri(controllers.routes.AccountController.addAccount().url());

    when(accountServiceMock.addAccount().thenReturn(true);
    assertEquals(OK, route(request).status());
});

running method停止了应用程序,然后您在路由请求时assert收到错误。

相关问题