Skip to content

Instantly share code, notes, and snippets.

@BenoitAverty
Created April 22, 2016 09:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save BenoitAverty/31cc2f3b3761b98c732406c10277cef7 to your computer and use it in GitHub Desktop.
Save BenoitAverty/31cc2f3b3761b98c732406c10277cef7 to your computer and use it in GitHub Desktop.
package com.example.unit.testing.application;
import ...;
@RunWith(HierarchicalContextRunner.class)
@ContextConfiguration(
classes = OrderApplicationTestContext.class,
loader = SpringApplicationContextLoader.class)
public class PlacingOrderTest {
/**
* Small hack to be able to load a Spring context without the JUnit Runner.
* using @Rule doesn't work either because of the nested classes.
*/
@Before
public void setUp() throws Exception {
new TestContextManager(this.getClass()).prepareTestInstance(this);
}
// System under test
@Autowired
OrderApplication orderApplication;
// mocks
@Autowired
CustomerRepository customerRepositoryMock;
@Autowired
CreditCardService creditCardServiceMock;
public class WithExistingCustomer {
private Long customerId;
@Before
public void beforeEach() {
Customer c = new Customer();
customerRepositoryMock.save(c);
customerId = c.getTid();
}
@Test
public void shouldReturnNewOrderId() {
Long result = orderApplication.placeOrder(9999L, customerId, "1234");
assertThat(result).isNotNull();
}
public class WhenCCIsNotMaxedOutNorExpired {
@Before
public void beforeEach() {
Mockito.when(creditCardServiceMock.isMaxedOut("123", 1.23)).thenReturn(false);
Mockito.when(creditCardServiceMock.expirationDate("123")).thenReturn(LocalDate.MAX);
}
@Test
public void shouldCreateAnOrderWithStatusInProgress() {
Long orderId = orderApplication.placeOrder(123L, customerId, "123");
String orderStatus = orderApplication.getOrderStatus(orderId);
assertThat(orderStatus).isEqualTo("IN PROGRESS");
}
@Test
public void shouldMakeOrderAvailableThroughCustomer() {
Long orderId = orderApplication.placeOrder(123L, customerId, "123");
List<Order> orders = orderApplication.findOrdersForCustomer(customerId);
assertThat(orders).isNotEmpty();
assertThat(orders).extracting(o -> o.getTid()).contains(orderId);
}
}
public class WhenCCIsMaxedOut {
@Before
public void beforeEach() {
Mockito.when(creditCardServiceMock.isMaxedOut("123", 1.23)).thenReturn(true);
}
@Test
public void shouldCreateAnOrderWithStatusPaymentFailed() {
Long orderId = orderApplication.placeOrder(123L, customerId, "123");
String orderStatus = orderApplication.getOrderStatus(orderId);
assertThat(orderStatus).isEqualTo("PAYMENT FAILED");
}
@Test
public void shouldNotMakeOrderAvailableThroughCustomer() {
Long orderId = orderApplication.placeOrder(123L, customerId, "123");
List<Order> orders = orderApplication.findOrdersForCustomer(customerId);
assertThat(orders).extracting(o -> o.getTid()).doesNotContain(orderId);
}
}
public class WhenCCExpiresInLessThanThreeMonths {
@Before
public void beforeEach() {
Mockito.when(creditCardServiceMock.isMaxedOut("123", 1.23)).thenReturn(false);
Mockito.when(creditCardServiceMock.expirationDate("123")).thenReturn(LocalDate.now().plusMonths(1));
}
@Test
public void shouldCreateAnOrderWithStatusPaymentFailed() {
Long orderId = orderApplication.placeOrder(123L, customerId, "123");
String orderStatus = orderApplication.getOrderStatus(orderId);
assertThat(orderStatus).isEqualTo("PAYMENT FAILED");
}
@Test
public void shouldNotMakeOrderAvailableThroughCustomer() {
Long orderId = orderApplication.placeOrder(123L, customerId, "123");
List<Order> orders = orderApplication.findOrdersForCustomer(customerId);
assertThat(orders).extracting(o -> o.getTid()).doesNotContain(orderId);
}
}
}
}
/**
* Configuration class for the spring test context of OrderApplication Test.
* <ul>
* <li>@Import real OrderApplication so it is available to the test class</li>
* <li>Scan the "domain" package to configure domain services (needed as
* dependencies of OrderApplication).</li>
* <li>Provide infrastructure services as mocks.</li>
* <li>Use spring data map repositories instead of JPA repositories</li>
* </ul>
*
* note that we DON'T include the "application" package in the ComponentScan
* because we don't need other application services. They don't depend on each
* other. We also don't put the @EnableJpaRepositories annotation, because we
* mock repositories. This isn't integration testing, we don't load any
* infrastructure layer.
*/
@Configuration
@Import(OrderApplication.class)
@ComponentScan("com.example.unit.testing.domain")
class OrderApplicationTestContext {
@Bean
public CreditCardService creditCardService() {
CreditCardService mock = Mockito.mock(CreditCardService.class);
Mockito.when(mock.expirationDate(Mockito.anyString())).thenReturn(LocalDate.MAX);
return mock;
}
@Bean
public OrderRepository orderRepository() {
return builder().mock(OrderRepository.class);
}
@Bean
public CustomerRepository customerRepository() {
return builder().mock(CustomerRepository.class);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment