Java – how to verify the use of Guice scope in testing?

I have some tests. If some Guice ranges are used incorrectly, I want to fail For example, @ singleton should not have any @ requestscoped or @ testscoped dependencies (of course, providers can also)

In production, this is partially resolved because eager singletons will be built before entering the scope, resulting in outofscopeexceptions But in the process of development, single people will create lazily within the scope, without any obvious problems

According to these two open questions, there seems to be no simple built-in way to do this Can it be implemented with SPI? I try to use a typelistener, but I don't know how to get dependencies of a given type

Solution

This is not a trivial problem, but it is definitely a good problem! There may be a scope constraint problem mentioned by the tester I think I can get JUnit runners to generate warnings with wrong binding exercises I will update this article later

Now there is an example of how to get the binding scope

model

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);
  }
}

test case

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;
      }
    });
  }
}

Scope object

@RequestScoped
public class RequestScopedObject extends Object {

}

@SessionScoped
public class SessionScopedObject extends Object {

}

@Singleton
public class SingletonScopedObject extends Object {

}
The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>