Frage

gab ich zu Google Guice die Verantwortung meiner Objekte der Verkabelung. Aber, wie kann ich testen, ob die Bindungen funktionieren gut?

Angenommen, wir eine Klasse A haben, die eine Abhängigkeit B hat. Wie kann ich, dass B-Test ist korrekt injiziert?

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

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

Beachten Sie, dass A eine getB() Methode nicht hat, und ich möchte behaupten, dass A.b nicht null.

War es hilfreich?

Lösung

Für jedes komplexes Guice Projekt, sollten Sie Tests hinzufügen, um sicherzustellen, dass die Module verwendet werden kann Ihre Klassen zu erstellen. In Ihrem Beispiel waren, wenn B eine Art, dass Guice nicht herausfinden kann, wie zu schaffen, dann wird Guice nicht in der Lage sein, A. zu erstellen Wenn A nicht den Server zu starten war nötig, wurde aber erforderlich, wenn der Server Handhabung war ein Anfrage, das würde zu Problemen führen.

In meinen Projekten, ich schreibe Tests für nicht-triviale Module. Für jedes Modul, verwende ich requireBinding () zu erklären, was das Modul-Bindungen erfordert aber nicht definiert. In meinen Tests, erstelle ich einen Guice Injektor das Modul unter Test und ein anderes Modul, das die erforderlichen Bindungen zur Verfügung stellt. Hier ist ein Beispiel unter Verwendung von JUnit4 und 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;
    }
  }
}

Beachten Sie, wie der Test fragt nur nach einem Anbieter. Das ist ausreichend, um festzustellen, dass Guice die Bindungen lösen kann. Wenn LoginService von einer Provider-Methode erstellt wurde, würde dieser Test nicht den Code in der Provider-Methode testen.

Dieser Test testet auch nicht, dass Sie das Richtige zu UserDao binded, oder dass UserDao richtig war scoped. Einige würden argumentieren, dass diese Art von Dingen sind selten lohnt; wenn es ein Problem gibt, geschieht es einmal. Sie sollten „-Test bis Angst abwechselnd zu Langeweile.“

Ich finde Modultests nützlich, weil ich oft neue Injektionspunkte hinzufügen, und es ist leicht zu vergessen, eine Bindung hinzuzufügen.

Die requireBinding() Anrufe können Guice fangen fehlende Bindungen helfen, bevor es Ihren Injektor zurück! Im obigen Beispiel ist der Test würde immer noch funktionieren, wenn die requireBinding() Anrufe nicht da waren, aber ich mag sie haben, weil sie dienen als Dokumentation.

Für kompliziertere Module (wie meine Root-Modul) verwende ich könnte Modules.override () Bindungen außer Kraft zu setzen, dass ich bei Testzeit nicht (zum Beispiel will, wenn ich überprüfen möchten, dass mein Stammobjekt angelegt werden, ich wahrscheinlich nicht wollen, es um ein Objekt zu erstellen, die eine Verbindung zur Datenbank wird). Für einfache Projekte könnten Sie nur die Top-Level-Modul testen.

Beachten Sie, dass Guice nicht inject nulls es sei denn, das Feld wie mit @Nullable kommentierten so Sie sehr selten benötigen, um sicherzustellen, dass die injizierten Objekte in Ihren Tests nicht-null sind. In der Tat, wenn ich mit Anmerkungen versehen Bauer mit @Inject ich nicht stören, wenn die Parameter null zu prüfen sind (in der Tat, meine Tests oft inject null in den Konstruktor die Tests einfach zu halten).

Andere Tipps

Eine weitere Möglichkeit, die Konfiguration zu testen, ist durch eine Testsuite mit, dass Ihre App End-to-End-Tests. Obwohl End-to-End-Tests nominell Anwendungsfälle testen überprüfen sie indirekt, dass Ihre Anwendung richtig konfiguriert ist, (dass alle Abhängigkeiten verdrahtet sind, etc etc). Unit-Tests auf der anderen Seite sollte ausschließlich auf der Domäne konzentrieren, und nicht auf den Kontext, in dem der Code bereitgestellt wird.

Ich stimme auch mit NamshubWriter Antwort. Ich bin bin nicht gegen Tests, dass die Check-Konfiguration, solange sie in einem separaten Testsuite Komponententests gruppiert sind.

IMHO, sollten Sie nicht, dass die Prüfung werden. Die Google Guice Jungs haben die Unit-Tests zu behaupten, dass die Injektionen wie erwartet - nach allem, dass das, was Guice ist so konzipiert, zu tun. Sie sollten nur Tests für Ihren eigenen Code (A und B) schreiben.

Ich glaube nicht, sollten Sie private Mitglieder testen gesetzt wird. Besser Test gegen die öffentliche Schnittstelle der Klasse. Wenn Mitglied „b“ nicht injiziert werden, werden Sie wahrscheinlich eine Nullpointer Ausführen Ihrer Tests erhalten, die viel Warnung sein sollte.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top