2016-01-01 87 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; 
    } 
} 
相關問題