2016-05-05 150 views
2

我需要模擬以下枚舉:使用Mockito嘲笑枚舉?

枚舉

public enum PersonStatus 
{ 
    WORKING, 
    HOLIDAY, 
    SICK 

} 

這是因爲它是在我測試下面的類中:

類測試:

public interface PersonRepository extends CrudRepository<Person, Integer> 
{ 
    List<Person> findByStatus(PersonStatus personStatus); 
} 

這是我目前的測試誘惑:

電流測試:

public class PersonRepositoryTest { 

    private final Logger LOGGER = LoggerFactory.getLogger(PersonRepositoryTest.class); 

    //Mock the PersonRepository class 
    @Mock 
    private PersonRepository PersonRepository; 

    @Mock 
    private PersonStatus personStatus; 

    @Before 
    public void setUp() throws Exception { 

     MockitoAnnotations.initMocks(this); 
     assertThat(PersonRepository, notNullValue()); 
     assertThat(PersonStatus, notNullValue()); 
    } 

    @Test 
    public void testFindByStatus() throws ParseException { 

     List<Person> personlist = PersonRepository.findByStatus(personStatus); 
     assertThat(personlist, notNullValue()); 
    } 
} 

這給以下錯誤:

錯誤:

org.mockito.exceptions.base.MockitoException: 
Cannot mock/spy class PersonStatus 
Mockito cannot mock/spy following: 
    - final classes 
    - anonymous classes 
    - primitive types 

我怎樣才能解決這個問題?

+2

你確定*你需要模擬'PersonStatus'嗎?你不能只使用實際的實例嗎? – khelwood

+0

我不認爲你想嘲笑枚舉 - 你想在你的測試中傳遞枚舉的各種值,並檢查結果是否如預期。 – assylias

+0

@assylias請提供答案,顯示如何做 – java123999

回答

3

您的testFindByStatus正試圖斷言findByStatus未返回空值。

如果不管方法工作的personStatus參數的時值以同樣的方式,只是通過他們的一個:

@Test 
public void testFindByStatus() throws ParseException { 
    List<Person> personlist = PersonRepository.findByStatus(WORKING); 
    assertThat(personlist, notNullValue()); 
} 

如果該行爲可能對其他可能的值不同,你可以測試每個它們:

@Test 
public void testFindByStatus() throws ParseException { 
    for (PersonStatus status : PersonStatus.values()) { 
     List<Person> personlist = PersonRepository.findByStatus(status); 
     assertThat(personlist, notNullValue()); 
    } 
} 
+0

不能我們迭代enum.values()? – Hiru

+1

@Hiru好點 – assylias

+0

你是怎麼解決org.mockito.exceptions.base.MockitoException的?我不明白你的答案。 –

-1

我創建其中枚舉可以被模擬的一個示例:

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

@RunWith(MockitoJUnitRunner.class) 
public class test { 

    enum Enum { 
     VALUE1, VALUE2 { 
     }; 

     public String customMethod() { 
      return name(); 
     } 
    } 

    @Mock 
    public Enum fixture = Enum.VALUE1; 

    @Test 
    public void test1() { 
     Mockito.when(fixture.customMethod()).thenReturn("customMethod()"); 
     System.out.println("1: " + fixture.customMethod()); // prints 1: customMethod() 
    } 

    @Test 
    public void test2() { 
     Mockito.when(fixture.name()).thenReturn("name()"); 
     System.out.println("2: " + fixture.name()); // prints: 2: null 
    } 

    @Test 
    public void test3() { 
     Mockito.when(fixture.toString()).thenReturn("toString()"); 
     System.out.println("3: " + fixture.toString());// prints: 3: toString() 
    } 
} 

這是非常奇怪:

  • 如果test2要麼test1test3之前運行時,它會失敗。
  • 的Mockito不能嘲笑name()方法調用
  • 如果Enum.VALUE2聲明之後的括號去掉,然後將的Mockito失敗
0

只是爲了完成圖片:

最新版本Mockito 2非常支持最終課堂的嘲笑。但是你必須首先明確地啓用這個新的實驗功能!

但是當然:如果你必須的話,你只是嘲笑一些東西。您對模擬Enum實例的渴望很可能是由於不瞭解這一點而導致的 - 或者因爲您很難在此處測試代碼。從這個意義上說,真正的答案將是尋找避免這種嘲笑的方式。