AbstractExhaustibleResource implements ResourceType { @Override public Resource deduct(Resource total, Resource deduction) throws NoEnoughResourcesException { checkResource(total); checkResource(deduction); if (total.getAmount() == -1) { return total; } if (deduction.getAmount() == -1) { throw new NoEnoughResourcesException(total, deduction, deduction); } final long resultAmount = total.getAmount() - deduction.getAmount(); if (resultAmount < 0) { throw new NoEnoughResourcesException( total, deduction, new ResourceImpl(getId(), -resultAmount, getDefaultUnit())); } return new ResourceImpl(getId(), resultAmount, getDefaultUnit()); }  @Override Resource aggregate(Resource resourceA, Resource resourceB); @Override Resource deduct(Resource total, Resource deduction);  }
@Test public void shouldFindDifferenceResourcesAmountsOnResourcesDeduction() throws Exception { final Resource deducted = resourceType.deduct( new ResourceImpl(TestResourceType.ID, 1000, TestResourceType.UNIT), new ResourceImpl(TestResourceType.ID, 500, TestResourceType.UNIT)); assertEquals(deducted.getType(), TestResourceType.ID); assertEquals(deducted.getAmount(), 500); assertEquals(deducted.getUnit(), TestResourceType.UNIT); }
@Test public void shouldReturnResourceWithMinusOneAmountWhenTotalResourceHasMinusOneOnResourcesDeduction() throws Exception { final Resource deducted = resourceType.deduct( new ResourceImpl(TestResourceType.ID, -1, TestResourceType.UNIT), new ResourceImpl(TestResourceType.ID, 500, TestResourceType.UNIT)); assertEquals(deducted.getType(), TestResourceType.ID); assertEquals(deducted.getAmount(), -1); assertEquals(deducted.getUnit(), TestResourceType.UNIT); }
@Test(expectedExceptions = NoEnoughResourcesException.class) public void shouldReturnResourceWithMinusOneAmountWhenDeductionResourceHasMinusOneOnResourcesDeduction() throws Exception { resourceType.deduct( new ResourceImpl(TestResourceType.ID, 1000, TestResourceType.UNIT), new ResourceImpl(TestResourceType.ID, -1, TestResourceType.UNIT)); }
@Test public void shouldThrowConflictExceptionWhenDeductionAmountMoreThanTotalAmountOnResourcesDeduction() throws Exception { try { resourceType.deduct( new ResourceImpl(TestResourceType.ID, 300, TestResourceType.UNIT), new ResourceImpl(TestResourceType.ID, 1000, TestResourceType.UNIT)); } catch (NoEnoughResourcesException e) { assertEquals( e.getMissingResources(), Collections.singletonList( new ResourceImpl(TestResourceType.ID, 700, TestResourceType.UNIT))); } }