2016-04-11 8 views
3

ich einen Controller wie dieses ich AccountDao und Account bin Injektion mitJersey 2 inject Abhängigkeiten in Unit-Test

ResourceConfig config = new ResourceConfig() 
       .packages("controller", "exception") 
       .register(new MyDIBinder()); 

Wo MyDIBinder ist enthält alle Bindungen

@Path("/") 
@Produces(MediaType.APPLICATION_JSON) 
@Consumes(MediaType.APPLICATION_JSON) 
public class AccountController implements CRUDController<Long, Account> { 

    private AccountDao accountDao; 
    private AccountService accountService; 

    @Inject 
    public AccountController(AccountDao accountDao, AccountService accountService) { 
     this.accountDao = accountDao; 
     this.accountService = accountService; 
    } 
... 

(zB

AccountDaoImpl accountDaoImpl = new AccountDaoImpl(); 
bind(accountDaoImpl).to(AccountDao.class); 

)

Nun möchte ich einen Komponententest für diesen Controller schreiben, ist es möglich, die gesamte AccountController-Instanz mit all ihren transitiven Abhängigkeiten in den Test zu injizieren?

So etwas wie

@Inject 
    AccountController accountController; 

Antwort

3

können Sie die wichtigsten IoC-Container verwenden und nur explizit die Testklasse injizieren. Jersey verwendet HK2 als sein DI-Framework, und sein IoC-Container ist das ServiceLocator, das über eine Methode inject(anyObject) verfügt, die beliebige Objekte mit Abhängigkeiten injizieren kann, die sich in seiner Registrierung befinden.

Zum Beispiel könnten Sie so etwas wie

public class InjectionTest { 

    @Inject 
    private TestController controller; 

    @Before 
    public void setUp() { 
     final Binder b = new AbstractBinder() { 
      @Override 
      public void configure() { 
       bindAsContract(TestController.class); 
      } 
     }; 
     final ServiceLocator locator = ServiceLocatorUtilities.bind(new TestBinder(), b); 
     locator.inject(this); 
    } 

    @Test 
    public void doTest() { 
     assertNotNull(controller); 
     String response = controller.get(); 
     assertEquals("Hello Tests", response); 
    } 
} 

tun Die ServiceLocatorUtilities Klasse ist eine Hilfsklasse, die uns die ServiceLocator leicht erstellen können, und dann inject(this) nennen wir nur die InjectionTest zu injizieren.

Wenn es scheint, dies für alle Controller-Tests zu wiederholen, können Sie eine abstrakte Basistestklasse erstellen. Vielleicht so etwas wie

public abstract class AbstractControllerTest { 

    protected ServiceLocator locator; 
    private final Class<?> controllerClass; 

    protected AbstractControllerTest(Class<?> controllerClass) { 
     this.controllerClass = controllerClass; 
    } 

    @Before 
    public void setUp() { 
     final AbstractBinder binder = new AbstractBinder() { 
      @Override 
      public void configure() { 
       bindAsContract(controllerClass); 
      } 
     }; 
     locator = ServiceLocatorUtilities.bind(new TestBinder(), binder); 
     locator.inject(this); 
    } 

    @After 
    public void tearDown() { 
     if (locator != null) { 
      locator.shutdown(); 
     } 
    } 
} 

Dann in Ihrer konkreten Klasse

public class TestControllerTest extends AbstractControllerTest { 

    public TestControllerTest() { 
     super(TestController.class); 
    } 

    @Inject 
    private TestController controller; 

    @Test 
    public void doTest() { 
     assertNotNull(controller); 
     assertEquals("Hello Tests", controller.get()); 
    } 
} 

Wenn Sie etwas mehr Zeit damit verbracht, ich bin sicher, dass Sie mit einem besseren abstrakten Testklasse-Design kommen können. Es war das erste, was mir in den Sinn kam.

Hinweis: Für alles, was für eine Anfrage gilt, müssen Sie sich vielleicht nur darüber lustig machen. Beim Ausführen der Einheit Tests gibt es keinen Anfragekontext, so dass der Test fehlschlägt. Auch

Siehe:

+0

Vielen Dank für die Antwort! Was ist ein TestBinder? – andreybavt

+0

Es ist ein Ordner, den ich benutzt habe, um mein Beispiel zu testen. Es enthielt nur eine einfache Service-Bindung. Für Sie wäre es MyDIBinding –

+0

@peeskillet Bitte füllen Sie diese Antwort mit einem TestBinder-Beispiel aus. – 4F2E4A2E

Verwandte Themen