2016-05-05 149 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实例的渴望很可能是由于不了解这一点而导致的 - 或者因为您很难在此处测试代码。从这个意义上说,真正的答案将是寻找避免这种嘲笑的方式。