2016-03-21 4 views
1

In unserem Projekt habe ich Module Scout.client, Scout.Server, Scout.Shared und Backend.Eclipse Scout Neon Mock Backend Service

Backend hat keine Abhängigkeiten scout.server und scout.shared, aber scout.server hat Abhängigkeiten Backend.

enter image description here

Innen Backend-Projekt habe ich alle Business-Logik und ruft alle externen Dienstleistungen.

Mein Problem ist, wenn ich Scout Dienste zu testen versuchen, die einen Dienst von Backend verwenden.

Da Scout etwas großartiges Werkzeug für spöttische Bohnen bieten wir als Bohnen unseren Service innerhalb Backend definiert als:

BEANS.getBeanManager().registerClass(CarService.class); 
BEANS.getBeanManager().registerClass(PartnerService.class); 

Both, CarService.class und PartnerService.class sind in Backend.

Wenn ich versuche, ein paar Tests zu schreiben, und ich füge hinzu @BeanMock in Test Service

@BeanMock 
private IPartnerService partnerService; 

ich Mock, aber dann wieder jede jede Funktion null ist, auch wenn ich

doReturn(PartnerBuilder.standardPartnerListWithOneElement()).when(this.partnerService) 
    .getPartners(any(Set.class)); 
schreiben

Wenn ich in meinem Test debuggen, bevor dieser Test mit Debugger aufgerufen wird, kann ich:

partnerService.getPartners(...) -> return a list of person 

was richtig ist, Wenn eine getestete Klasse diesen Dienst aufruft, gibt sie null aus.

Ich verstehe, dass diese Anmerkung @ApplicationScoped auf der Schnittstelle zu fehlen zurückzuführen sein könnte. Ohne dies gibt es keine Garantie, dass nur eine bean erstellt wird, und when Anweisung reagieren auf eine andere Kopie dieser Bean ...?

Ich konnte nicht Anmerkung auf Schnittstelle hinzufügen, da Backend keine Abhängigkeiten hat Module auszukundschaften.

Wie könnte ich mit dieser Art von Fällen umgehen?


Getestet Klasse:

public class UtilityPartner { 

    /** 
    * Method return service bean for getting partners by ids. 
    * 
    * @return 
    */ 
    private static IPartnerService getPartnerService() { 

    return BEANS.get(IPartnerService.class); 
    } 

    public static String getPartnerName(final Long partnerId) { 

    if (partnerId == null) { 
     return ""; 
    } 

    final List<Partner> partners = 
     (List<Partner>) getPartnerService().getPartners(Sets.newHashSet(partnerId)); 
    if (partners == null || partners.isEmpty()) { 
     return ""; 
    } 
    final Partner partner = partners.get(0); 
    return LookupUtil.createLookupDescription(partner.getId(), partner.getName()); 
    } 

} 

Testklasse ist:

@RunWith(ServerTestRunner.class) 
@RunWithSubject("anonymous") 
@RunWithServerSession(ServerSession.class) 
public class TestUtilityPartner { 

    @BeanMock 
    private IPartnerService partnerService; 

    @Before 
    public void init() { 
     doReturn(PartnerBuilder.standardPartnerListWithOneElement()).when(this.partnerService).getPartners(any(Set.class)); 

    } 

    @Test 
    public void getPartnerName() { 

     final String name = UtilityPartner.getPartnerName(10L); 
     Assert.assertEquals("My name", name); // NAME IS "" 
    } 
} 

Antwort

1

Ich denke, dass Sie Ihre Mock-Instanz im Bean Manager registrieren sollen (siehe bean registration im Scout Architektur Dokument). Sie sollten einen kleinen Auftrag (-10 000 is recommended for tests) verwenden, damit Ihr Spott die produktive Registrierung gewinnt. Der beste Ansatz besteht darin, die Klasse TestingUtility zu verwenden, um Ihren Schein zu registrieren oder die Registrierung aufzuheben.Vergessen Sie nicht die unregisterBean() Verfahren (bei dem Verfahren mit @After kommentierten) zu nennen:

import java.util.Collections; 

import org.eclipse.scout.rt.platform.BeanMetaData; 
import org.eclipse.scout.rt.platform.IBean; 
import org.eclipse.scout.rt.testing.shared.TestingUtility; 
import org.junit.After; 
import org.junit.Assert; 
import org.junit.Before; 
import org.junit.Test; 
import org.mockito.Mockito; 

public class TestUtilityPartner { 

    private IBean<?> beanRegistration; 

    @Before 
    public void init() { 
     partnerService = Mockito.mock(IPartnerService.class); 

     // Register the mock using the Bean meta information: 
     BeanMetaData beanData = new BeanMetaData(IPartnerService.class) 
      .withInitialInstance(partnerService) 
      .withApplicationScoped(true); 
     this.beanRegistration = TestingUtility.registerBean(beanData); 


     // Mockito behavior: 
     Mockito.doReturn(Collections.singletonList(new Partner(34L, "John Smith"))) 
      .when(partnerService).getPartners(Mockito.any(Set.class)); 
    } 

    @After 
    public void after() { 
     // Unregister the mocked services: 
     TestingUtility.unregisterBean(this.beanRegistration); 
    } 

    @Test 
    public void getPartnerName() { 
     String name = UtilityPartner.getPartnerName(10L); 
     Assert.assertEquals("10 - John Smith", name); 
    } 
} 

Ich bin nicht sicher, was @BeanMock (org.eclipse.scout.rt.testing.platform.mock.BeanMock) tut, aber nach Judith Gull's answer es wird nicht funktionieren:

Die Verwendung von @BeanMock hilft hier nicht, weil Sie keinen Anwendungsbereichsdienst verwenden:

In der Init-Methode ändern Sie das lokale Feld partnerService. In Ihrem Test rufen Sie jedoch UtilityPartner.getPartnerService auf, das eine neue Instanz erstellt (mit BEANS.get(IPartnerService.class)).

@BeanMock ist nützlicher für die Bequemlichkeit für das Spotten von Application Scoped Beans.

+0

Wow diese Arbeit! Ich habe zusätzliche Frage: wäre es besser, dass ich BEAN wie Sie hier gepostet registrieren, wenn ich meine Bean registriere (nicht im Test, sondern im PlatformListener)? –

+0

Ich kann das nicht im Kommentar beantworten. Verschieben Sie Ihre zweite Frage in einen anderen Thread: http://stackoverflow.com/questions/36164077/scout-bean-manager-registerclass-or-registerbean – Jmini

+1

Ich habe das Beispiel aktualisiert, um 'TestingUtility' zu verwenden. Sie sollten Ihren Code aktualisieren. – Jmini

2

@BeanMock Mit hier nicht helfen, weil Sie keinen Antrag scoped-Dienst verwenden:

In der init-Methode Sie den lokalen Feld Partnerservice ändern. In Ihrem Test rufen Sie jedoch UtilityPartner.getPartnerService auf, das eine neue Instanz erstellt (mit BEANS.get(IPartnerService.class)).

@BeanMock ist nützlicher für die Bequemlichkeit für das Spotten von Application Scoped Beans.

Sie können Ihre Bohnen immer manuell registrieren as shown by Jmini. Bitte vergessen Sie nicht, die Bean nach dem Test wieder abzumelden!

Wir empfehlen die Verwendung von org.eclipse.scout.rt.testing.shared.TestingUtility.registerBean(BeanMetaData), die automatisch einen Testauftrag hinzufügt und @TunnelToServer Annotationen entfernt.

Verwandte Themen