2016-01-01 54 views
-1
package pl.mielecmichal.news.services.news; 

import org.junit.Before; 
import org.junit.Test; 
import org.junit.runner.RunWith; 
import org.mockito.Mock; 
import org.mockito.runners.MockitoJUnitRunner; 

import pl.mielecmichal.news.entities.news.News; 
import pl.mielecmichal.news.entities.newssources.NewsSource; 
import pl.mielecmichal.news.repositories.news.NewsRepository; 

import static java.util.Arrays.asList; 
import static org.mockito.Mockito.*; 

import java.net.MalformedURLException; 
import java.net.URL; 
import java.time.LocalDateTime; 
import java.util.ArrayList; 
import java.util.Arrays; 
import java.util.List; 


public class NewsServiceTest { 

    NewsService newsService; 

    NewsRepository newsRepository; 

    private static final String FIRST_AUTHOR = "[email protected]"; 
    private static final String FIRST_TITLE = "First Title"; 
    private static final String FIRST_CONTENT = "First Content Content Content"; 
    private static final String FIRST_URL = "http://localhost/first"; 

    private static final String SECOND_AUTHOR = "[email protected]"; 
    private static final String SECOND_TITLE = "Second"; 
    private static final String SECOND_CONTENT = "Second Content"; 

    private static final String THIRD_AUTHOR = "[email protected]"; 
    private static final String THIRD_TITLE = "Third Title"; 
    private static final String THIRD_CONTENT = "Third Content"; 

    private final News firstNews = firstCorrectNews(); 
    private final News secondNews = secondCorrectNews(); 
    private final News thirdNews = thirdCorrectNews(); 
    private final NewsSource source = correctSource(); 

    public NewsServiceTest() throws MalformedURLException { 

    } 

    @Before 
    public void setUp() throws MalformedURLException { 
     newsRepository = mock(NewsRepository.class); 
     newsService = new NewsService(newsRepository); 
    } 

    @Test 
    public void saveNewNewses_savedNewsesGivenAgain_shouldSaveOnlyNew() { 
     // given 
     List<News> newses = new ArrayList<>(); 
     newses.add(firstNews); 
     newses.add(secondNews); 

     when(newsRepository.countByNewsSourceAndAuthorAndTitle(source, FIRST_AUTHOR, FIRST_TITLE)).thenReturn(0L); 
     when(newsRepository.countByNewsSourceAndAuthorAndTitle(source, SECOND_AUTHOR, SECOND_TITLE)).thenReturn(1L); 

     // when 
     newsService.saveNewNewses(newses); 

     // then 
     verify(newsRepository, times(1)).save(asList(firstNews)); 
     verify(newsRepository, never()).save(newses); 
    } 

    private News firstCorrectNews() { 
     News news = new News(); 
     news.setAuthor(FIRST_AUTHOR); 
     news.setTitle(FIRST_TITLE); 
     news.setContent(FIRST_CONTENT); 
     news.setNewsSource(source); 
     return news; 
    } 

    private News secondCorrectNews() { 
     News news = new News(); 
     news.setAuthor(SECOND_AUTHOR); 
     news.setTitle(SECOND_TITLE); 
     news.setContent(SECOND_CONTENT); 
     news.setNewsSource(source); 
     return news; 
    } 

    private News thirdCorrectNews() { 
     News news = new News(); 
     news.setAuthor(THIRD_AUTHOR); 
     news.setTitle(THIRD_TITLE); 
     news.setContent(THIRD_CONTENT); 
     news.setNewsSource(source); 
     return news; 
    } 

    private NewsSource correctSource() throws MalformedURLException { 
     NewsSource source = new NewsSource(); 
     source.setUrl(new URL(FIRST_URL)); 
     source.setUpdateTime(LocalDateTime.now()); 
     return source; 
    } 

} 

我在调试器下进行检查,并且countBy方法总是返回O,但参数在我的SUT中不同且正确。它看起来像Mockito 区分方法的参数。干杯!Mockito的mock返回相同的值,尽管有不同的参数

我添加完整的源代码来显示常量是正确的。

+1

你可能还需要指定什么'FIRST_AUTHOR','SECOND_AUTHOR','FIRST_TITLE','SECOND_TITLE','source',以及如何使用的嘲弄。 – khelwood

+0

问题已更新 –

回答

0

好的,问题是初始化新的顺序和来源。

当我创建firstNews,secondNews,thirdNews时,源对象为null。但在我的测试中,它已完全初始化。

private final NewsSource source = correctSource(); //should be here 
private final News firstNews = firstCorrectNews(); 
private final News secondNews = secondCorrectNews(); 
private final News thirdNews = thirdCorrectNews(); 
private final NewsSource source = correctSource(); //not here 
1

尽管这一问题是主要的字段的顺序,有一些事情可以做,以减少双方再次发生这种错误的可能性,并清理你的测试相当多。

首先,您的三种方法 - firstCorrectNews,secondCorrectNewsthirdCorrectNews - 所有参数略有不同的参数完全相同。统一他们的目的更有意义。

private News correctNews(final String author, final String title, final String content, final NewsSource source) { 
    final News news = new News(); 
    news.setAuthor(author); 
    news.setTitle(title); 
    news.setContent(content); 
    news.setNewsSource(source); 
    return news; 
} 

如果使用这个方法来引导你的测试news对象,你不得不在源每次传球,这样你就不会得到任何的依赖的状态赶上你的测试对象整体。

虽然我们在这里,但也值得修改correctSource方法,以便我们传递URL而不是再次呈现状态。

private NewsSource correctSource(final String url) throws MalformedURLException { 
    final NewsSource source = new NewsSource(); 
    source.setUrl(new URL(url)); 
    source.setUpdateTime(LocalDateTime.now()); 
    return source; 
} 

接下来,我们可以利用的Mockito的亚军类,这样我们就不必新了嘲笑在@Before条款。这样可以使代码小很多,并且可以预测模拟类和测试类。

@RunWith(MockitoJUnitRunner.class) 
public class NewsServiceTest { 

    @Mock 
    NewsRepository newsRepository; 

    @InjectMocks 
    NewsService newsService; 

    // other code to follow 

} 

现在,让我们把它放在一起。这应该是你正在测试的同样的事情,主要区别是:

  • 自举
  • 你嘲笑都有明确的规定
  • 预期的数据时,有少了很多重复的代码,特别是
  • ,你真正关心的所有测试数据在特定的测试,当你想要编写更多的测试,这有助于
  • 您的测试数据也范围,它允许你运行这个测试并行
012隔离


@RunWith(MockitoJUnitRunner.class) 
public class NewsServiceTest { 

    @Mock 
    NewsRepository newsRepository; 

    @InjectMocks 
    NewsService newsService; 

    @Test 
    public void saveNewNewses_savedNewsesGivenAgain_shouldSaveOnlyNew() { 
     // given 
     final String FIRST_AUTHOR = "[email protected]"; 
     final String FIRST_TITLE = "First Title"; 
     final String FIRST_CONTENT = "First Content Content Content"; 
     final String URL = "http://localhost/first"; 
     final String SECOND_AUTHOR = "[email protected]"; 
     final String SECOND_TITLE = "Second"; 
     final String SECOND_CONTENT = "Second Content"; 

     final List<News> newses = new ArrayList<>(); 

     final NewsSource newsSource = correctSource(URL); 
     final News firstNews = correctNews(FIRST_AUTHOR, FIRST_TITLE, FIRST_CONTENT, newsSource); 
     final News secondNews = correctNews(SECOND_AUTHOR, SECOND_TITLE, SECOND_CONTENT, newsSource); 

     newses.add(firstNews); 
     newses.add(secondNews); 

     // when 

     when(newsRepository.countByNewsSourceAndAuthorAndTitle(newsSource, FIRST_AUTHOR, FIRST_TITLE)).thenReturn(0L); 
     when(newsRepository.countByNewsSourceAndAuthorAndTitle(newsSource, SECOND_AUTHOR, SECOND_TITLE)).thenReturn(1L); 
     newsService.saveNewNewses(newses); 

     // then 
     verify(newsRepository).save(asList(firstNews)); 
     verify(newsRepository, never()).save(newses); 
    } 

    private News correctNews(final String author, final String title, final String content, final NewsSource source) { 
     final News news = new News(); 
     news.setAuthor(author); 
     news.setTitle(title); 
     news.setContent(content); 
     news.setNewsSource(source); 
     return news; 
    } 


    private NewsSource correctSource(final String url) throws MalformedURLException { 
     NewsSource source = new NewsSource(); 
     source.setUrl(new URL(url)); 
     source.setUpdateTime(LocalDateTime.now()); 
     return source; 
    } 
} 
相关问题