4

私はまだモキットを学んでおり、今はモックを注入する方法を学んでいます。

他のオブジェクトに依存する特定のメソッドを持つテスト対象のオブジェクトがあります。これらのオブジェクトは、他のオブジェクトに依存しています。特定のものをモックし、それらのモックを実行中のあらゆる場所 (メソッドの制御フロー全体) で使用したいと考えています。

たとえば、次のようなクラスがあるとします。

public class GroceryStore {
    public double inventoryValue = 0.0;
    private shelf = new Shelf(5);
    public void takeInventory() {
        for(Item item : shelf) {
            inventoryValue += item.price();
        }
    }
}

public class Shelf extends ArrayList<Item> {
    private ProductManager manager = new ProductManager();
    public Shelf(int aisleNumber){
        super(manager.getShelfContents(aisleNumber);
    }
}

public class ProductManager {
    private Apple apple;
    public void setApple(Apple newApple) {
        apple = newApple;
    }
    public Collection<Item> getShelfContents(int aisleNumber) {
        return Arrays.asList(apple, apple, apple, apple, apple);
    }
}

次の行に沿った部分でテスト コードを記述する必要があります。

....
@Mock
private Apple apple;
... 
when(apple.price()).thenReturn(10.0);
... 

...
@InjectMocks
private GroceryStore store = new GroceryStore();
...
@Test
public void testTakeInventory() {
   store.takeInventory();
   assertEquals(50.0, store.inventoryValue);
}

apple.price() が呼び出されるたびに、モックのリンゴが使用されるようにします。これは可能ですか?

編集:
重要な注意...
モックしたいオブジェクトを含むクラスには、そのオブジェクトのセッターがあります。ただし、テストしているレベルでは、そのクラスへのハンドルは実際にはありません。したがって、例に従って、ProductManager には Apple 用のセッターがありますが、GroceryStore オブジェクトから ProductManager を取得する方法がありません。

4

1 に答える 1

2

問題は、依存するオブジェクトをnew注入する代わりに呼び出して作成することです。に注入ProductManagerしますShelf(たとえば、コンストラクターで)、および inject Shelfinto GroceryStore。次に、テストでモックを使用します。を使用する場合@InjectMocksは、setter メソッドで注入する必要があります。

コンストラクターでは、次のようになります。

public class GroceryStore {
  public double inventoryValue = 0.0;
  private shelf;

  public GroceryStore(Shelf shelf) {
    this.shelf = shelf;
  }

  public void takeInventory() {
    for(Item item : shelf) {
      inventoryValue += item.price();
    }
  }
}

public class Shelf extends ArrayList<Item> {
  private ProductManager manager;

  public Shelf(int aisleNumber, ProductManager manager) {
    super(manager.getShelfContents(aisleNumber);
    this.manager = manager;
  }
}

public class ProductManager {
  private Apple apple;
  public void setApple(Apple newApple) {
    apple = newApple;
  }
  public Collection<Item> getShelfContents(int aisleNumber) {
    return Arrays.asList(apple, apple, apple, apple, apple);
  }
}

次に、依存するすべてのオブジェクトをモックしてテストできます。

@Mock
private Apple apple;
... 
when(apple.price()).thenReturn(10.0);

@InjectMocks
private ProductManager manager = new ProductManager();

private Shelf shelf = new Shelf(5, manager);
private GroceryStore store = new GroceryStore(shelf);

//Then you can test your store.
于 2010-11-03T10:08:08.820 に答える