Java 模拟特定的类对象存根会导致测试失败

Java 模拟特定的类对象存根会导致测试失败,java,junit,nullpointerexception,mockito,Java,Junit,Nullpointerexception,Mockito,我正在读取一个正在填充我的类对象的json对象,所以我在模拟我的类对象,不确定哪种方式是最好的方式。以下是我的方法: public List<Person> readFile(String filename) { List<Person> list = new ArrayList<Person>(); JSONParser parser = new JSONParser(); int count = 0; try {

我正在读取一个正在填充我的类对象的json对象,所以我在模拟我的类对象,不确定哪种方式是最好的方式。以下是我的方法:

    public List<Person> readFile(String filename) {
    List<Person> list = new ArrayList<Person>();
    JSONParser parser = new JSONParser();
    int count = 0;

    try {
        Object obj = parser.parse(new FileReader(
               filename));

       JSONObject jsonObject = (JSONObject) obj;
       JSONArray array = (JSONArray) jsonObject.get("people");
        //System.out.println("Debug: " + array.size());
        if(array != null) {
            while (count < array.size()) {
                Person person = new Person();
                JSONObject people = (JSONObject) array.get(count);
                person.setName((String) people.get("name"));
                Long age = (Long) people.get("age");
                person.setAge(Integer.valueOf(age.intValue()));
                person.setSex((String) people.get("sex"));
                person.setIllness((String) people.get("illness"));
                list.add(person);
                count++;
            }
        }

    } catch (Exception e) {
        e.printStackTrace();
    }
    return list;
}
公共列表读取文件(字符串文件名){
列表=新的ArrayList();
JSONParser=新的JSONParser();
整数计数=0;
试一试{
Object obj=parser.parse(新文件读取器(
文件名);
JSONObject JSONObject=(JSONObject)对象;
JSONArray数组=(JSONArray)jsonObject.get(“人”);
//System.out.println(“调试:+array.size());
if(数组!=null){
while(count
这将获取一个文件名并返回一个列表,在本例中是一个特定的文件对象列表。以下是我目前的测试:

package pricing;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.junit.BeforeClass;
import org.junit.Test;

import com.pricing.DiscountPricing;
import com.pricing.model.Person;

 @SuppressWarnings("deprecation")
public class DiscountPricingTest {

private static DiscountPricing mockDPclass;
private static Person mockPerson1;
private static Person mockPerson2;
private static Person mockPerson3;

@BeforeClass
public static void setUp() {
    mockDPclass = mock(DiscountPricing.class);
    mockPerson1 = new Person(50, "Allergies", "Kelly", "female");
    mockPerson2 = new Person(40, "Sleep Apnea", "Josh", "male");
    mockPerson3 = new Person(20, "Heart Disease", "Brad", "male");
}

@Test
public void readFileTest() {
    String filename = "Consumers.json";
    DiscountPricing dpclass = new DiscountPricing();
    List<Person> allPeople = dpclass.readFile(filename);
    List<Person> mockPeople = new ArrayList<Person>();
    mockPeople.add(mockPerson1);
    mockPeople.add(mockPerson2);
    mockPeople.add(mockPerson3);
    assertEquals(mockPeople.size(), allPeople.size());
    assertTrue(allPeople.get(0).getName().equals("Kelly"));
}
}
套餐定价;
导入静态org.junit.Assert.assertEquals;
导入静态org.junit.Assert.assertTrue;
导入静态org.mockito.mockito.mock;
导入静态org.mockito.mockito.when;
导入java.util.ArrayList;
导入java.util.array;
导入java.util.List;
导入org.junit.BeforeClass;
导入org.junit.Test;
进口com.pricing.DiscountPricing;
导入com.pricing.model.Person;
@抑制警告(“弃用”)
公共类折扣价格测试{
私有静态折扣类;
私人静态模拟人1;
私人静态模拟人2;
私人静态模拟人3;
@课前
公共静态无效设置(){
mockDPclass=mock(折扣定价.class);
mockPerson1=新人(50,“过敏”、“凯利”、“女性”);
mockPerson2=新人(40,“睡眠呼吸暂停”、“乔希”、“男性”);
mockPerson3=新人(20名,“心脏病”、“布拉德”、“男性”);
}
@试验
public void readFileTest(){
字符串filename=“Consumers.json”;
折扣定价dpclass=新折扣定价();
列出allPeople=dpclass.readFile(文件名);
List mockPeople=new ArrayList();
mockPeople.add(mockPerson1);
mockPeople.add(mockPerson2);
mockPeople.add(mockPerson3);
assertEquals(mockPeople.size()、allPeople.size());
assertTrue(allPeople.get(0.getName().equals)(“Kelly”);
}
}

看看我在Mockito中使用的模拟是否正确?

您还没有模拟要测试的类。i、 e.:
mockedYourClass=mock(YourClass.class)。您应该在测试类的setUp()方法中执行此操作

此外,在测试之前,您没有使用模拟数据对模拟类的方法进行存根,即:
when(mockDPclass.readFile(“Consumers.json”))。然后返回(Arrays.asList(mockPerson1、mockPerson2、mockPerson3))
您应该将其放在setUp()方法的末尾

在readFileTest()方法中,您可以执行以下操作:

List<Person> persons = mockDPclass.readFile("Consumers.json");
assertEquals(3, persons.size());
Person person = persons.get(0);
assertEquals("Kelly", person.getName());
List persons=mockDPclass.readFile(“Consumers.json”);
资产质量(3人.规模());
Person=persons.get(0);
assertEquals(“Kelly”,person.getName());

下面是一个很好的教程,介绍如何在java中开始模拟:

您还没有模拟要测试的类。i、 e.:
mockedYourClass=mock(YourClass.class)。您应该在测试类的setUp()方法中执行此操作

此外,在测试之前,您没有使用模拟数据对模拟类的方法进行存根,即:
when(mockDPclass.readFile(“Consumers.json”))。然后返回(Arrays.asList(mockPerson1、mockPerson2、mockPerson3))
您应该将其放在setUp()方法的末尾

在readFileTest()方法中,您可以执行以下操作:

List<Person> persons = mockDPclass.readFile("Consumers.json");
assertEquals(3, persons.size());
Person person = persons.get(0);
assertEquals("Kelly", person.getName());
List persons=mockDPclass.readFile(“Consumers.json”);
资产质量(3人.规模());
Person=persons.get(0);
assertEquals(“Kelly”,person.getName());

下面是一个很好的java模拟入门教程:

一般来说,模拟对象的原因是因为它们是您要测试的东西所必需的依赖项,模拟它们可以简化真实对象的制作,并为您提供一种控制期望和检查交互的方法

在本例中,您正在测试一个函数,以验证它是否正确地从文件中读取数据。您的依赖项是:

  • 您正在读取的文件名
  • JSONParser
    实例在执行该解析的方法中为您提供了
    new
  • FileReader
    实例可以在读取文件的方法中创建
    new
鉴于此,您可以做两件事:

1) 使用测试所针对的测试数据创建假文件。那么你的测试应该是这样的

@Test
public void readFileTest() {
    DiscountPricing dp = new DiscountPricing();
    List<Person> emptyList = dp.readFile("test_file_empty.json");
    assertThat(emptyList, is(empty()));

    List<Person> singleItemList = dp.readFile("test_file_single.json");
    assertThat(singleItemList, hasSize(1));
    // TODO: Assert state of Person at singleItemList(0) is correct

    List<Person> multiItemList = dp.readFile("test_file_multi.json");
    assertThat(mutilItemList, hasSize(2));
    // TODO: Assert state of each person in list is correct
}
使用选项
1
可以对真实数据进行测试,这是对代码的更真实的测试,设置起来也更容易,但是数据保存在单独的文件中,因此可以从测试中删除

使用选项
2
可以清楚地在代码中列出测试用例,使其更易于阅读和更新,但由于您必须在代码中伪造所有样本数据,所以测试用例有点冗长

您选择哪一个主要取决于风格和适合您的方式,但我个人可能更喜欢选项
1


希望有帮助

一般来说,模拟对象的原因是,它们是您试图测试的对象所必需的依赖项,模拟它们可以简化真实对象的制作,并为您提供一种控制期望和检查交互的方法

在您的例子中,您正在测试func