如何创建虚假数据和数据对象以进行单元测试?

时间:2018-11-18 18:29:45

标签: java junit junit5

我有一个实现缓存的类,我想为此编写一个JUnit测试。
该类实现并与以下方法进行接口:

public void insert(Object key, Object value);  
public Object getFromCache(Object key);

,基本实现是单例。
我正在编写JUnit测试,但我不知道如何正确地使用数据创建虚拟缓存以用于测试。
现在我正在做:

@Test
public void myTest() {  
    MyCache cache = MyCache.getInstance();  
    populateWithData(cache);  
    //test cache  
    asserEquals etc  
}  

如何避免使用getInstance()而不在每次测试中填充?

3 个答案:

答案 0 :(得分:3)

显然我对您的问题有误读。

作为另外两个答案,如果您希望拥有一个特定的缓存,可以在运行每个测试用例时从中读取内容,则可以使用“ @before”方法,该方法将初始化要在测试用例中使用的对象。在调用每个测试用例之前,将调用定义的每个“ @before”方法。这意味着您可以编写代码来实例化该对象一次,而不是多次。

注意,如果您想在测试用例中做一些不同的事情,请考虑在其顶部添加自定义项,而不是编辑您的@before方法,因为这将影响您的所有测试用例。

为清楚起见,我将包含一些代码:

MyCache cache = null;

@before
public void initCache(){
    cache = MyCache.getInstance();  
    populateWithData(cache);  
}

// ... rest of your program here ...

原始答案

如果要对更复杂的对象进行更多的精美测试,可以使用此选项。仍可以与“ @before”注释一起使用

您可以尝试mockito ...

这基本上是一个模拟函数或类的框架,您完全不希望完全实现它,特别是对于测试。

这是一个使用假列表的示例:

import static org.mockito.Mockito.*;

// mock creation
List mockedList = mock(List.class);

// using mock object - it does not throw any "unexpected interaction" exception
mockedList.add("one");
mockedList.clear();

// selective, explicit, highly readable verification
verify(mockedList).add("one");
verify(mockedList).clear();

// you can mock concrete classes, not only interfaces
LinkedList mockedList = mock(LinkedList.class);

// stubbing appears before the actual execution
when(mockedList.get(0)).thenReturn("first");

// the following prints "first"
System.out.println(mockedList.get(0));

// the following prints "null" because get(999) was not stubbed
System.out.println(mockedList.get(999));

您基本上可以告诉mockito您希望在对象上调用哪些函数,以及期望结果是什么...非常通用。我希望它将满足您的需求。

答案 1 :(得分:2)

在每次测试之前“重置”单例。可以在here中找到更多详细信息。

例如:

@Before
public void resetMyCacheSingleton() throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
   Field instance = MyCache.class.getDeclaredField("instance");
   instance.setAccessible(true);
   instance.set(null, null);
}

答案 2 :(得分:1)

您可以使用 @BeforeClass 注释来做一些普通的事情,并且可能是计算量大的事情。

此操作仅在所有测试用例之前先运行

@BeforeClass
public static void myTest() {  
    MyCache cache = MyCache.getInstance();  
    populateWithData(cache);  
    //test cache  
    asserEquals etc  
} 

P.S。由于@BeforeClass只能与静态方法一起使用,因此populateWithData()也必须是静态的。并且由于populateWithData()方法是静态的,因此在其内部使用的变量也必须是静态的。

您还可以检查 @AfterClass 以清除/重置一些数据/资源。