我正在嘗試使用Guice
嘗試使用Play framework 2.4.6
進行控制器測試時遇到錯誤。它發生在Controller中的任何view.render
代碼中。 redirect
不會產生此問題。控制器測試 - CacheManager已關閉。它不能再使用
堆棧:
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([email protected])) (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([email protected])) (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());
});
}
任何他LP讚賞!
編輯:我確定了導致問題的確切的東西,但我仍然不知道爲什麼。
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
會話時,測試方法與控制器view.render
沿設置RequestBuilder
,這個錯誤發生。
這是不管我是否在我的html或甚至在控制器中使用這樣的會話。任何人都知道這裏發生了什麼?
你在哪裏實例化你的應用程序?你不應該在(classLoader).in(Mode.TEST).build();'中使用'application = new GuiceApplicationBuilder()。 – Kris
@Kris我相信所有需要的設置都已經在使用'@ Before''註釋的setup方法中。 再次實例化''application''會導致''沒有執行play.Application被綁定.'''''''' – DxHito
也許你是對的。無論如何,我在我的測試用例'ClassLoader classLoader = FakeApplication.class中啓動一個FakeApplication。getClassLoader();應用程序= new GuiceApplicationBuilder()。in(classLoader).in(Mode.TEST).build(); Helpers.start(應用程序);'。但是在我看來,在Play中編寫測試時,更多的嘗試和錯誤。如果有效,我堅持下去。 :) – Kris