package net.safedata.springboot.training.d03s03;

import net.safedata.springboot.training.d03s03.model.Product;
import net.safedata.springboot.training.d03s03.repository.ProductRepository;
import net.safedata.springboot.training.d03s03.service.ProductService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import static org.hamcrest.core.Is.is;
import static org.hamcrest.core.IsNot.not;
import static org.junit.Assert.*;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Mockito.*;

@RunWith(MockitoJUnitRunner.class)
public class ProductServiceTest {

    @Mock
    private ProductRepository productRepository;

    // the tested service; also called 'system under test'
    @InjectMocks
    private ProductService productService;

    @Test
    public void shouldGetProductsWhenThereAreAvailableProducts() {
        // arrange
        final List<Product> products = Arrays.asList(new Product(1, "Asus"), new Product(2, "Dell"));
        when(productRepository.findAll()).thenReturn(products);

        // act
        final List<Product> resulted = productService.getProducts();

        // assert
        assertNotNull(resulted);
        assertThat(resulted.size(), is(products.size()));
    }

    @Test
    public void shouldNotGetAnyProductsWhenThereAreNoAvailableProducts() {
        when(productRepository.findAll()).thenReturn(new ArrayList<>());

        final List<Product> resulted = productService.getProducts();

        assertThat(resulted.size(), is(0));
    }

    @Test
    public void shouldGetAProductByIdWhenTheProductExists() {
        Product product = mock(Product.class);
        final String mockedName = "mocked name";
        when(product.getName()).thenReturn(mockedName);
        when(product.getId()).thenReturn(20);

        when(productRepository.findOne(anyInt())).thenReturn(product);

        final Product resulted = productService.getProduct(25);

        assertNotNull(resulted);
        assertThat(resulted.getName(), is(mockedName));
        assertThat(resulted.getId(), not(0));
    }

    @Test(expected = IllegalArgumentException.class)
    public void shouldGetAProductByIdWhenTheProductDoesNotExist() {
        when(productRepository.findOne(anyInt())).thenReturn(null);

        final Product resulted = productService.getProduct(13);

        assertNull(resulted);
    }

    @Test
    public void shouldSaveAProduct() {
        Product product = mock(Product.class);
        final String mockedName = "mocked name";
        when(product.getName()).thenReturn(mockedName);

        final String response = productService.saveProduct(product);

        verify(productRepository, times(1)).save(product);

        assertNotNull(response);
        assertThat(response.length(), not(0));
    }
}

@@ -944,32 +944,34 @@
 %0A%0A    @Test%0A    
+//
 public void shou
@@ -1009,32 +1009,140 @@
 bleProducts() %7B%0A
+    public void givenThereAreAvailableProducts_whenRetrievingProducts_thenProductsAreRetrievedCorrectly() %7B%0A
         // arran
@@ -2543,33 +2543,8 @@
     
- final Product resulted =
  pro
@@ -2574,39 +2574,8 @@
 13);
-%0A%0A        assertNull(resulted);
 %0A   

Use a 'given / when / then' naming sample