1

私たちのプロジェクトには、モジュール scout.client、scout.server、scout.shared、backend があります。

バックエンドには scout.server と scout.shared への依存関係はありませんが、scout.server にはバックエンドへの依存関係があります。

ここに画像の説明を入力

バックエンド プロジェクト内には、すべてのビジネス ロジックがあり、すべての外部サービスを呼び出しています。

私の問題は、バックエンドからいくつかのサービスを使用するスカウト サービスをテストしようとするときです。

scout は Bean をモックするための優れたツールを提供するため、バックエンド内のサービスを次のように Bean として定義しました。

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

CarService.class と PartnerService.class の両方がバックエンドにあります。

いくつかのテストを作成しようとして、 @BeanMock をテストのサービスに追加すると

@BeanMock
private IPartnerService partnerService;

私はモックを取得しますが、すべての関数を返すたびに、たとえ私が書いても、すべての関数はnullです

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

テストでデバッグすると、このテストがデバッガーで呼び出される前に、次を取得できます。

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

正しいことですが、テストされたクラスがこのサービスを呼び出すと、null が返されます。

これは、 interface に注釈がないことが原因である可能性があることを理解しています@ApplicationScoped。これがないと、1 つだけbeanが作成され、whenステートメントがその Bean の別のコピーに反応するという保証はありません...?

バックエンドがスカウト モジュールに依存していないため、インターフェイスに注釈を追加できませんでした。

この種のケースをどのように処理できますか?


テストされたクラスは次のとおりです。

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

}

テストクラスは次のとおりです。

 @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 ""
     }
}
4

2 に答える 2

2

ここでは、アプリケーション スコープのサービスを使用@BeanMockしていないため、以下を使用しても役に立ちません。

init メソッドでは、ローカル フィールド partnerService を変更しています。ただし、テストでは、新しいインスタンスを作成する UtilityPartner.getPartnerService を呼び出します ( を使用BEANS.get(IPartnerService.class))。

@BeanMockアプリケーションスコープのBeanをモックするのに便利です。

Jmini で示されているように、Bean をいつでも手動で登録できます。テストが終わったら、Bean を再度登録解除することを忘れないでください。

を使用することをお勧めしorg.eclipse.scout.rt.testing.shared.TestingUtility.registerBean(BeanMetaData)ます。これにより、テスト オーダーが自動的に追加され、@TunnelToServer注釈が削除されます。

于 2016-04-05T14:45:43.317 に答える
1

モック インスタンスを Bean マネージャーに登録する必要があると思います ( Scout Architecture Document のBean 登録を参照してください)。モックが生産的な登録を勝ち取るためには、小さな注文 (テストには -10 000 が推奨されます) を使用する必要があります。最善の方法は、TestingUtilityクラスを使用してモックを登録/登録解除することです。メソッドを呼び出すことを忘れないでくださいunregisterBean()( で注釈が付けられたメソッド内で@After):

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

@BeanMock( org.eclipse.scout.rt.testing.platform.mock.BeanMock) が何をしているのかわかりませんが、 Judith Gull の回答によると、機能しません。

ここでは、アプリケーション スコープのサービスを使用@BeanMockしていないため、以下を使用しても役に立ちません。

init メソッドでは、ローカル フィールド partnerService を変更しています。ただし、テストでは、新しいインスタンスを作成する UtilityPartner.getPartnerService を呼び出します ( を使用BEANS.get(IPartnerService.class))。

@BeanMockアプリケーションスコープのBeanをモックするのに便利です。

于 2016-03-22T06:27:38.443 に答える