2017-02-21 14 views
1

Я знаком с SpringBoot, и я написал небольшое приложение. Он имеет ProductRepository, распространяющийся на CrudRepository. Мой ProductService это:Использование Mockito в приложении SpringBoot

public interface ProductService { 
    Iterable<Product> listAllProducts(); 
    Product getProductById(Integer id); 
    Product saveProduct(Product product); 
    void deleteProduct(Integer id); 
} 

В ProductServiceImpl класс авто провода в ProductRepository и обеспечивает реализацию с использованием ProductRepository.

Мое приложение работает как ожидалось, и именно так я тестирую репозиторий.

@RunWith(SpringRunner.class) 
@SpringBootTest(classes = {RepositoryConfiguration.class}) 
public class ProductRepositoryTest { 
    private ProductRepository productRepository; 
    @Autowired 
    public void setProductRepository(ProductRepository productRepository) { 
    this.productRepository = productRepository; 
    } 
    @Test 
    public void testSaveProduct(){ 
    //setup product 
    Product product = new Product(); 
    product.setDescription("Shirt"); 
    product.setPrice(new BigDecimal("18.95")); 
    product.setProductId("1234");   
    assertNull(product.getId()); //null before save 
    productRepository.save(product); 
    assertNotNull(product.getId()); //not null after save 
    //fetch from DB 
    Product fetchedProduct = productRepository.findOne(product.getId()); 
    //should not be null 
    assertNotNull(fetchedProduct);  
} 
} 

Я хочу знать, как я могу модульное тестирование ProductRepository без внешней зависимости (что выше теста есть, и поэтому не квалифицируется в качестве модульного тестирования. Я считаю, что это больше из интеграционного теста).

Кроме того, как я могу выполнить тестирование моего ProductService? Я попытался насмешливо ProductRepository и Product с Mockito, как это:

public class ProductServiceImplTest { 
    private ProductServiceImpl productServiceImpl; 
    private ProductRepository productRepository; 
    private Product product; 

    @Before 
    public void setupMock() { 
    MockitoAnnotations.initMocks(this); 
    productServiceImpl=new ProductServiceImpl(); 
    productRepository = mock(ProductRepository.class); 
    product = mock(Product.class); 
    } 

    @Test 
    public void testRetrieveById() throws Exception { 
    when(productRepository.findOne(5)).thenReturn(product); 
    assertEquals(product, productServiceImpl.getProductById(5)); 
    } 
} 

Но это то, что я получаю:

java.lang.NullPointerException 
at  
    ProductServiceImpl.getProductById(ProductServiceImpl.java:24) 
at ProductServiceImplTest.testRetrieveById(ProductServiceImplTest.java:36) 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke 
(NativeMethodAccessorImpl.java:62) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke 
(DelegatingMethodAccessorImpl.java:43) 
at java.lang.reflect.Method.invoke(Method.java:497) 
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall 
    (FrameworkMethod.java:50) 
at org.junit.internal.runners.model.ReflectiveCallable.run 
(ReflectiveCallable.java:12) 
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) 
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) 
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) 
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) 
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78) 
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57) 
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) 
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) 
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) 
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) 
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) 
at org.junit.runners.ParentRunner.run(ParentRunner.java:363) 
at org.junit.runner.JUnitCore.run(JUnitCore.java:137) 
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68) 
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:51) 
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:237) 
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70) 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
at java.lang.reflect.Method.invoke(Method.java:497) 
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147) 

Могу ли я с помощью Mockito.mock() правильно? И какая разница, если я использую вместо этого Mockito.spy()? Любая помощь будет высоко оценена.

ответ

1

Если вы хотите написать модульные тесты, удалите все ненужные аннотации, которые используются для тестирования интеграции.

Кроме того, необходимо инициировать издевается в методе @Before:

public class ProductServiceImplTest { 
    @InjectMocks 
    private ProductServiceImpl productServiceImpl; 
    @Mock 
    private ProductRepository productRepository; 
    @Mock 
    private Product product; 

    @Before 
    public void setupMock() { 
    MockitoAnnotations.initMocks(this); 
    } 

Я думаю, в вашем случае, используя mock должно быть достаточно.

Единственный раз, когда вы должны использовать spy, чтобы вызвать его на классе, что вы проверяете в вашем случае будет:

productServiceImpl=new ProductServiceImpl(); 
prodServiceSpy = spy(productServiceImpl); 

и издеваться некоторые из методов, реализация которых не требуется для вызова или вызова с помощью специальной реализации, требуемой тестовым сценарием.

+0

Спасибо за четкий ответ - именно то, что я искал. Я отредактировал вопрос, но до сих пор не могу понять, почему генерируется NullPointerException. – user2693135

+0

вам нужно вставить репозиторий или любую другую зависимость в Сервис. Я обновил этот пример с помощью аннотаций mockito .. упрощает жизнь –

+0

Работает как шарм - Спасибо. Маркировка как принято. – user2693135

Смежные вопросы