0

次のサーブレット コードを検討してください。

public class AddDevice extends JsonServlet {
    private static final long serialVersionUID = 1L;

    @Override
    protected void doGet(final JsonServletRequest request,
            final JsonServletResponse response) throws ServletException,
            IOException {
        try {
            final DeviceEntity device = new DeviceEntity();

            device.type =
                    FleetManagerDatabaseHelper
                            .deviceTypesAccessor()
                            .queryForId(Integer.valueOf(
                                    request.getParameter(DeviceTypeEntity._ID)));

            device.sn = request.getParameter(DeviceEntity._SN);
            device.status = Long.valueOf(0);

            FleetManagerDatabaseHelper.devicesAccessor().create(device);
        }
        catch (final SQLException e) {
            throw new ServletException("device already exists");
        }
    }
}

このコードは、DeviceEntity と FleetManagerDatabaseHelper クラスに依存します。ここで、作成されたエンティティに正しいタイプ、sn、およびステータス値が入力されていることを確認するテストを作成したいと思います。この目的のために、FleetManagerDatabaseHelperMockup クラスを作成できます。

最小限の変更で、ここに Google Guice (またはその他のもの) をどのように適用しますか?

4

1 に答える 1

1

最初のステップは、依存性注入を設計することです。つまり、コンストラクターと静的メソッドを避け、代わりに必要なインスタンスを取り入れます。それらのタイプはProvider<DeviceEntity>DevicesAccessor、およびのようDeviceTypesAccessorです。

Provider非常に単純な Guice インターフェースであり、引数のない単一のメソッドを介して、その型引数にあるクラスのインスタンスを提供しますget()。バインドされている場合Foo、Guice はバインド方法を自動的に認識しますProvider<Foo>。インスタンスが高価な場合、またはサーブレットの存続期間中に複数のインスタンスが必要な場合 (実際に行っているように)、非常に便利です。

依存性注入のリファクタリング後、クラスは次のようになります。

public class AddDevice extends JsonServlet {
  private static final long serialVersionUID = 1L;

  private final Provider<DeviceEntity> deviceEntityProvider;
  private final DevicesAccessor devicesAccessor;
  private final DeviceTypesAccessor deviceTypesAccessor;

  @Inject
  public AddDevice(Provider<DeviceEntity> deviceEntityProvider,
      DevicesAccessor devicesAccessor,
      DeviceTypesAccessor deviceTypesAccessor>) {
    this.deviceEntityProvider = deviceEntityProvider;
    this.devicesAccessor = devicesAccessor;
    this.deviceTypesAccessor = deviceTypesAccessor;
  }

  @Override
  protected void doGet(final JsonServletRequest request,
      final JsonServletResponse response) throws ServletException,
      IOException {
    try {
      final DeviceEntity device = deviceEntityProvider.get();

      device.type = deviceTypesAccessor.queryForId(
          Integer.valueOf(request.getParameter(DeviceTypeEntity._ID)));
      device.sn = request.getParameter(DeviceEntity._SN)
      device.status = Long.valueOf(0);

      devicesAccessor.create(device);
    } catch (final SQLException e) {
      throw new ServletException("device already exists");
    }
  }
}

この時点で、返されるインスタンスを追跡する Provider を、モックの DevicesAccessor とモックの DeviceTypesAccessor とともに渡すことで、テストを非常に簡単に作成できます。(私はMockitoをお勧めします。) 独自の Provider インターフェースを作成して を削除すると@Inject、Guice を使用する必要さえありません。テストでは、そのコンストラクターを引き続き使用できますが、次のようなコンストラクターで Java EE を満たす必要があります。

public AddDevice() {
  this(new NewDeviceEntityProvider(),
      FleetManagerDatabaseHelper.deviceTypesAccessor(),
      FleetManagerDatabaseHelper.devicesAccessor());
}

private class NewDeviceEntityProvider implements Provider<DeviceEntity> {
  @Override public DeviceEntity get() {
    return new DeviceEntity();
  }
}

しかし、Guice を使用してボイラープレートを削除したい場合は、 Guice を記述してModuleください。モジュールは、DeviceTypesAccessor と DevicesAccessor を FleetManagerDatabaseHelper が返すインスタンスにバインドする必要があります。Guice は、引数のないコンストラクターがあり、自動的DeviceEntityに注入できることを確認します。(あなたが私にそれがどのように見えるかを拡張したい場合はコメントしてください。)DeviceEntityProvider<DeviceEntity>Module

お役に立てれば!

于 2012-10-05T15:28:16.623 に答える