简体   繁体   English

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

[英]How can I create fake data and the data object for unit testing?

I have a class that implements a cache and I want to write a JUnit test for it. 我有一个实现缓存的类,我想为此编写一个JUnit测试。
The class implements and interface with methods like: 该类实现并与以下方法进行接口:

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

and the basic implementation is a singleton. 基本实现是单例。
I am writing a JUnit test but I don't know how to properly create a dummy cache with data in order to use for testing. 我正在编写一个JUnit测试,但我不知道如何使用数据正确创建一个虚拟缓存以用于测试。
Right now I am doing: 现在我正在做:

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

How can I avoid using the getInstance() and not populate on each test? 如何避免使用getInstance()而不在每次测试中填充?

Apparently I slightly misread your question. 显然我稍微误解了您的问题。

As the other two answers state, if you want to have a specific cache which you can read from when running each testcase, you could use a ´@before´ method, which initializes your object to be used in your testcase. 正如其他两个答案所述,如果您想拥有一个特定的缓存,可以在运行每个测试用例时从中读取内容,则可以使用“ @before”方法,该方法初始化要在测试用例中使用的对象。 Each ´@before´ method defined is called prior to calling each testcase . 在调用每个测试用例之前,将先调用定义的每个“ @before”方法。 This means that you can write the code to instantiate the object once instead of many times. 这意味着您可以编写代码来实例化该对象一次,而不是多次。

Note that if you want to do something different in a testcase, consider adding the customization at the top of that, instead of edition your @before method, since that will impact all your testcases. 请注意 ,如果您想在测试用例中做一些不同的事情,请考虑在自定义项的顶部添加自定义项,而不是对@before方法进行版本@before ,因为这将影响所有测试用例。

Just for clarity's sake, I will include some code: 为了清楚起见,我将包含一些代码:

MyCache cache = null;

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

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

Original answer : 原始答案

You can use this if you want to do more fancy testing of more complicated objects. 如果要对更复杂的对象进行更多的精美测试,则可以使用此方法。 This can still be used in conjunction with the ´@before´ annotation 仍可以与“ @before”注释一起使用

You could try mockito ... 您可以尝试模仿 ...

This is basically a framework to mock off a function or class, that you are not interested in implementing in its totally, especially for testing. 基本上,这是一个模拟功能或类的框架,您完全不希望完全实现该功能或类,尤其是对于测试。

Here is a sample using a mocked off list: 这是一个使用模拟列表的示例:

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));

You can basically tell mockito which functions you expect to call on the object, and what you expect the result to be... very versatile. 您基本上可以告诉mockito您希望在对象上调用哪些函数,以及预期结果将是什么...非常通用。 I expect that it will fulfill your needs. 我希望它将满足您的需求。

'Reset' singleton before each test. 每次测试前“重置”单身人士。 More details can be found here . 可以在此处找到更多详细信息。

For example: 例如:

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

You can use @BeforeClass annotation to do something which will be common and may be computational expensive stuff. 您可以使用@BeforeClass批注来做一些普通的事情,并且可能是昂贵的计算工作。

This will ran only once before all the testcases . 这将在所有测试用例之前只运行一次

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

PS Since @BeforeClass can be used with static method only, populateWithData() needs to be static as well. PS由于@BeforeClass只能与静态方法一起使用,因此populateWithData()也必须是静态的。 and since populateWithData() method is static, variables used inside it must be static as well. 并且由于populateWithData()方法是静态的,因此其内部使用的变量也必须是静态的。

You can also check @AfterClass to clean/reset some data/resources. 您还可以检查@AfterClass清除/重置一些数据/资源。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM