2016-04-11 164 views
3

我有使用澤西2依賴注入單元測試

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

哪裏MyDIBinder是這樣

@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; 
    } 
... 

我注入AccountDao和的AccountService控制器包含的所有綁定(例如

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

現在我想爲這個控制器編寫一個單元測試,是否有可能將整個AccountController實例及其所有傳遞依賴注入到測試中?

喜歡的東西

@Inject 
    AccountController accountController; 

回答

3

您可以使用主IoC容器,只是明確地注入測試類。 Jersey使用HK2作爲它的DI框架,它的IoC容器是ServiceLocator,它有一個方法inject(anyObject),它可以注入任何具有註冊表中依賴關係的對象。

例如,你可以做這樣的事情

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

ServiceLocatorUtilities類是一個輔助類,使我們能夠輕鬆地創建ServiceLocator,然後我們只需要調用inject(this)注入InjectionTest

如果您對所有控制器測試重複進行此操作,您可能需要創建一個抽象基礎測試類。也許像

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

然後在您的具體類

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

如果你花了一些時間,我相信你能想出一個更好的抽象測試類的設計。這是我首先想到的。

注意:對於任何請求範圍,您可能需要嘲笑它。當運行單元測試時,沒有請求上下文,所以測試將失敗。

另請參見:

+0

謝謝你的回答!什麼是TestBinder? – andreybavt

+0

這是我用來測試我的例子的活頁夾。它只包含一個簡單的服務綁定。對你而言,這將是MyDIBinding –

+0

@peeskillet請使用TestBinder示例完成此響應。 – 4F2E4A2E