ketchyn
ketchyn

Reputation: 514

how to use mocks properly

I have foolowing class which I would like to mock:

BusineesLayer:

/**
 * Created by Alexandr on 14.05.2016.
 */
public class BusineesLayer {
    public  OrderModel orderModel;
    public DbService dbService;
    ...

    public BusineesLayer(OrderModel orderModel,DbService dbService) {
        this.orderModel = orderModel;
        dbService = dbService;
    }
    public BusineesLayer() {

    }

    public boolean checkItemsInDb(List<Items> items) throws HandleOrderExeption {
       ...
      return result

    }



    public boolean handleOrder() throws HandleOrderExeption {

        checkItemsInDb(orderModel.getItemsList());

        boolean res =dbService.addOrder(orderModel.getItemsList(),
                            orderModel.getCustumerName(),
                            countTotalSum(orderModel.getItemsList())
                            );

        return res;
    }


}

I would like to test hanldeOrder() method and in order to make it less excess insted of checkItemsinDb() inside invoke "true";

So, my test looks like this:

@Test
    public void handleorderTest() {
   ...
        BusineesLayer layer = Mockito.mock(BusineesLayer.class);

        layer.dbService = busineesLayer.dbService;
        layer.orderModel = busineesLayer.orderModel;

        Mockito.when(layer.checkItemsInDb()).thenReturn(true);

        boolean  res = layer.handleOrder();

        assertThat(res, equalTo(true));
    }

but it always return false and doesn't go through handlOrder() at all

Is any ways to solve it? Or how can I refactor my code to test it?

Upvotes: 0

Views: 89

Answers (1)

Compass
Compass

Reputation: 5937

You do not test mocks, you use mocks to help you test.

I think you've just become confused at how you are using mocks. Mocks allow us to simulate and can responses to objects we are testing. If you're testing the handleOrder method, then you should mock anything that interacts with that method, in this case DbService and OrderModel.

@Test
public void handleorderTest() {
    BusineesLayer layer = new BusineesLayer(); //we are testing this!
    DbService dbService = Mockito.mock(DbService.class);
    OrderModel orderModel = Mockito.mock(OrderModel.class);

    layer.dbService = dbService;
    layer.orderModel = orderModel;

    Mockito.when(orderModel.getItemsList()).thenReturn(new ArrayList<Items>());
    Mockito.when(dbService.foo()).thenReturn(true);

    //mock up multiple calls so your service will provide true

    boolean  res = layer.handleOrder();

    assertThat(res, equalTo(true));

    //repeat for false, and so on
}

If, however, you are trying to test the dbService call, then you should create a test for it without the business layer at all. The business layer doesn't depend on anything except calls to other methods, so whether you use those real objects or mocked versions of those objects, the functionality should be the same. The business logic only appears to fail if DBService or OrderModel break, so you would test service and model separately (without involving the business layer) to test those.

Upvotes: 1

Related Questions