문제

나는 Google Guice에게 내 객체를 배선 할 책임을 주었다. 그러나 바인딩이 잘 작동하는지 어떻게 테스트 할 수 있습니까?

예를 들어, 수업이 있다고 가정합니다 A 의존성이 있습니다 B. B가 올바르게 주입 된 것을 어떻게 테스트 할 수 있습니까?

class A {
    private B b;
    public A() {}

    @Inject
    public void setB(B b) {
        this.b = b
    }
}

그것을주의해라 A 아무것도 없습니다 getB() 방법과 나는 그것을 주장하고 싶습니다 A.b 그렇지 않습니다 null.

도움이 되었습니까?

해결책

모든 복잡한 Guice 프로젝트의 경우, 모듈을 사용하여 클래스를 만들 수 있는지 확인하기 위해 테스트를 추가해야합니다. 예에서 B가 Guice가 작성 방법을 알 수없는 유형이라면 Guice는 A를 만들 수 없습니다. A가 서버를 시작할 필요가 없지만 서버가 A를 처리 할 때 필요한 경우 A가 필요합니다. 요청, 문제가 발생합니다.

내 프로젝트에서는 사소한 모듈에 대한 테스트를 작성합니다. 각 모듈에 대해 사용합니다 필요에 따라 () 모듈에 필요한 바인딩을 선언하려면 모듈이 필요하지만 정의하지는 않습니다. 테스트에서 테스트중인 모듈과 필요한 바인딩을 제공하는 다른 모듈을 사용하여 Guice 인젝터를 만듭니다. Junit4 및 Jmock을 사용하는 예는 다음과 같습니다.

/** Module that provides LoginService */
public class LoginServiceModule extends AbstractModule {
  @Override 
  protected void configure() {
    requireBinding(UserDao.class);
  }

  @Provides
  LoginService provideLoginService(UserDao dao) {
    ...
  }
}

@RunWith(JMock.class)
public class LoginServiceModuleTest {
  private final Mockery context = new Mockery();

  @Test
  public void testModule() {
    Injector injector = Guice.createInjector(
        new LoginServiceModule(), new ModuleDeps());

    // next line will throw an exception if dependencies missing
    injector.getProvider(LoginService.class);
  }

  private class ModuleDeps extends AbstractModule {
    private final UserDao fakeUserDao;

    public ModuleDeps() {
      fakeUserDao = context.mock(UserDao.class);
    }

    @Override 
    protected void configure() {}

    @Provides
    Server provideUserDao() {
      return fakeUserDao;
    }
  }
}

테스트가 제공자 만 요구하는 방법에 주목하십시오. Guice가 바인딩을 해결할 수 있다고 판단하기에 충분합니다. 공급자 메소드에 의해 LoginService가 생성 된 경우이 테스트는 제공자 메소드에서 코드를 테스트하지 않습니다.

이 테스트는 또한 당신이 옳은 것을 UserDao, 또는 UserDao 올바르게 범위를 지정했습니다. 어떤 사람들은 그러한 유형의 것들이 거의 확인할 가치가 없다고 주장 할 것입니다. 문제가 있으면 한 번 발생합니다. "두려움이 지루함으로 바뀔 때까지 테스트해야합니다."

나는 종종 새로운 주입 지점을 추가하기 때문에 모듈 테스트가 유용하며 바인딩을 추가하는 것을 잊기 쉽습니다.

그만큼 requireBinding() 통화는 Guice가 인젝터를 반환하기 전에 누락 된 바인딩을 잡는 데 도움이 될 수 있습니다! 위의 예에서는 테스트가 여전히 작동합니다. requireBinding() 전화는 없었지만 문서로 사용하기 때문에 나는 그들을 갖는 것을 좋아합니다.

더 복잡한 모듈 (루트 모듈과 같은)의 경우 사용할 수 있습니다. modules.override () 테스트 시간에 원하지 않는 바인딩을 무시하려면 (예 : 루트 객체를 생성할지 확인하려면 데이터베이스에 연결할 객체를 만들고 싶지 않을 것입니다). 간단한 프로젝트의 경우 최상위 모듈 만 테스트 할 수 있습니다.

Guice에 주목하십시오 널을 주입하지 않습니다 필드가 주석이없는 경우 @Nullable 따라서 주입 된 객체가 테스트에서 널 없는지 확인할 필요가 거의 없습니다. 사실, 제작자에게 주석을 달 때 @Inject 나는 매개 변수가 있는지 확인하지 않습니다. null (사실, 내 테스트는 종종 주입합니다 null 테스트를 단순하게 유지하기 위해 생성자로).

다른 팁

구성을 테스트하는 또 다른 방법은 앱 엔드 투 엔드를 테스트하는 테스트 스위트를 갖는 것입니다. 엔드 투 엔드 테스트는 명목상으로 사용되는 사용 사례를 사용하지만 앱이 올바르게 구성되어 있는지 간접적으로 확인합니다 (모든 종속성이 유선 등). 반면에 단위 테스트는 코드가 배포되는 컨텍스트가 아닌 도메인에만 초점을 맞추어야합니다.

또한 Namshubwriter의 답변에 동의합니다. 나는 단위 테스트와 별도의 테스트 스위트로 그룹화되는 한 구성을 확인하는 테스트에 반대하지 않습니다.

IMHO, 당신은 그것을 테스트해서는 안됩니다. Google Guice Guys는 주사가 예상대로 작동한다고 주장하기 위해 단위 테스트를 받았습니다. 결국 Guice가 설계된 것입니다. 자신의 코드 (A 및 B)에 대한 테스트 만 작성해야합니다.

개인 회원이 설정되어 있어야한다고 생각하지 않습니다. 수업의 공개 인터페이스에 대해 테스트하는 것이 좋습니다. 멤버 "B"가 주입되지 않으면 테스트를 실행하는 NullPointerException을 얻을 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top