這不是一個小問題,但絕對是一個很好的問題!可能會有一位測試人員提到您提到的作用域綁定問題。我想我可以讓一個Junit跑步者用錯誤的綁定練習來產生警告。我將在稍後更新這篇文章。
現在有一個示例如何獲取綁定範圍。
模塊
public class ScopeTestModel extends ServletModule {
@Override
protected void configureServlets() {
super
.configureServlets();
bind(Key.get(Object.class, Names.named("REQ1"))).to(Object.class).in(ServletScopes.REQUEST);
bind(Key.get(Object.class, Names.named("REQ2"))).to(RequestScopedObject.class);
bind(Key.get(Object.class, Names.named("SINGLETON1"))).to(Object.class).asEagerSingleton();
bind(Key.get(Object.class, Names.named("SINGLETON2"))).to(Object.class).in(Scopes.SINGLETON);
bind(Key.get(Object.class, Names.named("SINGLETON3"))).to(SingletonScopedObject.class);
bind(Key.get(Object.class, Names.named("SESS1"))).to(Object.class).in(ServletScopes.SESSION);
bind(Key.get(Object.class, Names.named("SESS2"))).to(SessionScopedObject.class);
}
}
的TestCase
public class TestScopeBinding {
private Injector injector = Guice.createInjector(new ScopeTestModel());
@Test
public void testRequestScope() throws Exception {
Binding<Object> req1 = injector.getBinding(Key.get(Object.class, Names.named("REQ1")));
Binding<Object> req2 = injector.getBinding(Key.get(Object.class, Names.named("REQ2")));
Scope scope1 = getScopeInstanceOrNull(req1);
Scope scope2 = getScopeInstanceOrNull(req2);
Assert.assertEquals(ServletScopes.REQUEST,scope1);
Assert.assertEquals(ServletScopes.REQUEST,scope2);
}
@Test
public void testSessionScope() throws Exception {
injector.getAllBindings();
Binding<Object> sess1 = injector.getBinding(Key.get(Object.class, Names.named("SESS1")));
Binding<Object> sess2 = injector.getBinding(Key.get(Object.class, Names.named("SESS2")));
Scope scope1 = getScopeInstanceOrNull(sess1);
Scope scope2 = getScopeInstanceOrNull(sess2);
Assert.assertEquals(ServletScopes.SESSION,scope1);
Assert.assertEquals(ServletScopes.SESSION,scope2);
}
@Test
public void testSingletonScope() throws Exception {
injector.getAllBindings();
Binding<Object> sng1 = injector.getBinding(Key.get(Object.class, Names.named("SINGLETON1")));
Binding<Object> sng2 = injector.getBinding(Key.get(Object.class, Names.named("SINGLETON2")));
Binding<Object> sng3 = injector.getBinding(Key.get(Object.class, Names.named("SINGLETON3")));
Scope scope1 = getScopeInstanceOrNull(sng1);
Scope scope2 = getScopeInstanceOrNull(sng2);
Scope scope3 = getScopeInstanceOrNull(sng3);
Assert.assertEquals(Scopes.SINGLETON,scope1);
Assert.assertEquals(Scopes.SINGLETON,scope2);
Assert.assertEquals(Scopes.SINGLETON,scope3);
}
private Scope getScopeInstanceOrNull(final Binding<?> binding) {
return binding.acceptScopingVisitor(new DefaultBindingScopingVisitor<Scope>() {
@Override
public Scope visitScopeAnnotation(Class<? extends Annotation> scopeAnnotation) {
throw new RuntimeException(String.format("I don't know how to handle the scopeAnnotation: %s",scopeAnnotation.getCanonicalName()));
}
@Override
public Scope visitNoScoping() {
if(binding instanceof LinkedKeyBinding) {
Binding<?> childBinding = injector.getBinding(((LinkedKeyBinding)binding).getLinkedKey());
return getScopeInstanceOrNull(childBinding);
}
return null;
}
@Override
public Scope visitEagerSingleton() {
return Scopes.SINGLETON;
}
public Scope visitScope(Scope scope) {
return scope;
}
});
}
}
範圍內的對象
@RequestScoped
public class RequestScopedObject extends Object {
}
@SessionScoped
public class SessionScopedObject extends Object {
}
@Singleton
public class SingletonScopedObject extends Object {
}
謝謝,這當然是一個難題。爲了測試綁定是否是單例,還有'Scopes.isSingleton()'。難題的另一部分是我被卡住的地方。我已經找到了即將發佈的Guice 4解決方案,但如果可能的話,我仍然會喜歡Guice 3解決方案。 –