当前位置: 首页 > 知识库问答 >
问题:

模拟对象的自动连线字段在模拟中返回null

陆寒
2023-03-14

我有一个类。并且我已经编写了一个类的单元测试方法的学生服务类。我的代码如下:-

@Component
@EnableAutoConfiguration
public class StudentService {

@Autowired
StudentInstitutionMapper studentInstitutionMapper;

public Integer getPresentStudentCount(StudentParams studentParam) {
    // TODO Auto-generated method stub
    StudentInstitutionExample example = new StudentInstitutionExample();
    StudentInstitutionExample.Criteria criteria = example.createCriteria();
    criteria.andActiveYnEqualTo("Y");
    criteria.andDeleteYnEqualTo("N");
    criteria.andIsPresentEqualTo("Y");
    criteria.andInstitutionTestIdEqualTo(studentParam.getInstitutionTestId());
    List<StudentInstitution> studentInstitutionList = studentInstitutionMapper.selectByExample(example);//line 8 in method
    return studentInstitutionList.size();
}


}

在我的单元测试课上,我编写了以下方法。

    @Test
    public void testStudentService_getPresentStudentCount1()
    {



        StudentService service=new StudentService();
        StudentParams studentParam=mock(StudentParams.class);

        Integer institutionTestId=3539;
        when(studentParam.getInstitutionTestId()).thenReturn(institutionTestId);


        int i=service.getPresentStudentCount(studentParam);
        assertEquals(0,i);

    }

当我执行测试类,我得到错误。这是因为在类中,在方法的第8行中,学生机构映射字段为null。这只发生在模拟对象上。如何获得模拟对象的自动生成字段?

共有3个答案

颛孙英才
2023-03-14

有一个简单的解决方案,不涉及mockito的高级注释:

您可以像这样重构StudentService

public class StudentService {

    private final StudentInstitutionMapper studentInstitutionMapper;

    public StudentService(StudentInstitutionMapper studentInstitutionMapper) {
       this.studentInstitutionMapper = studentInstitutionMapper;
    }
}

这个解决方案是我最喜欢的,因为当我在测试中创建StudentService时,我可以准确地看到它需要什么依赖项,它们的类型。因此,即使不打开StudentService类的源代码,我也可以提供mock/real实现。

这种类型的注入的另一个好处(构造函数注入与您在问题中使用的字段注入相反)是没有任何东西会破坏字段的封装。

注意事项:

>

  • 我没有将@Autowired放在构造函数上,因为在最新版本的spring中,只要有一个构造函数,就不需要它(对于单元测试来说,它根本不相关)。

    如果您关心构造函数的样板代码,您可以使用Lombok并放置注释来为您生成all args构造函数。结合注释1,这允许完全删除构造函数代码

    另外,我不打算在这里开始现场注入与构造函数注入的“圣战”,我只是说明这种方法,因为之前没有人在其他答案中提到过,技术上它解决了问题中提出的问题。请随意在谷歌上搜索这个话题。

  • 贺奕
    2023-03-14

    可以使用@Mock注释注入自动生成的类。在许多情况下,您应该使用@InjectMocks注释创建您的测试类实例,由于这种注释,您的模拟可以直接注入。

    @RunWith(PowerMockRunner.class)
    @PrepareForTest({StudentService.class})
    public class StudentServiceTest {
    
    @InjectMocks
    StudentService service;
    
    @Mock
    StudentInstitutionMapper studentInstitutionMapper;
    
    @Test
    public void testStudentService_getPresentStudentCount1()
    {
        MockitoAnnotations.initMocks(this);
    
        StudentParams studentParam=mock(StudentParams.class);
    
        Integer institutionTestId=3539;
        when(studentParam.getInstitutionTestId()).thenReturn(institutionTestId);
    
    
        int i=service.getPresentStudentCount(studentParam);
        assertEquals(0,i);
    
    
    }
    

    这将有助于更好的解释:@Mock和@injectmock之间的区别

    秦渝
    2023-03-14

    尝试在测试类中这样声明对象studentInstitutionMapper

    @Mock
    StudentInstitutionMapper studentInstitutionMapper;
    
     类似资料:
    • 我想知道是否有办法模拟正在自动连线的场。 考虑下面的情况。 我有一个班级名A 另一个B类看起来像这样 现在我想为这个方法编写junit。 我知道有一种方法可以像这样模拟自动连线场。 但我的问题是- eg 请提出建议,否则就没有办法了???? 我不想改变私人生活。我也不想添加getter和setter或reflection。我只是想知道,在创建一个类的新对象之后,有没有办法模拟B实例。

    • 调试时,在带有的行中弹出一个NullPointerException,类为。

    • 如何模拟返回已强制转换的模拟对象的方法。 试验方法。

    • 所以我想做一些事情 但我得到了空异常

    • 问题内容: 我想在Python的xlsxwriter中模拟Excel自动拟合功能。根据此网址,不直接支持它:http : //xlsxwriter.readthedocs.io/worksheet.html 但是,在工作表中的每个单元格之间循环并确定列的最大大小,然后使用worksheet.set_column(row,col,width)设置宽度应该非常简单。 使我无法撰写本文的复杂因素包括:

    • 尽管遵循了多种不同的资源,但我无法让PowerMock在新的时间工作。以下是我的示例: 我试图模拟构造函数,使其指向这样的点: 我做错什么了吗?我应该提到,我正在gradle项目中使用PowerMock。这似乎与https://automationrhapsody.com/mock-new-object-creation-powermock/,所以我不知道为什么它对我不起作用。