繁体   English   中英

使用Mockito调用Service类的嵌套方法时获取NullPointerException

[英]Getting NullPointerException while calling nested method of Service class using mockito

我正在为我的Service类编写JUnit测试用例。 我创建了虚拟数据来了解我的情况。

@Service
MainClass {
    @Autowired
    C c;
    public void someServiceMethod(){
        ResultClass someResult = c.getResult(string,string, int, int, List<String>,boolean);
    }
}

@Service
public class C {
    @Autowired
    SomeRepository someRepository;
    public ResultClass getResult(string,string, int, int, List<String>,boolean){
        ABC returnSomeClassObject = someRepository.getSomeData(String,int,int);
    }
}

@Test
MainClassTest {
    @MockBean
    SomeRepository someRepository;
    when(someRepository.getSomeData(anyString(),anyInt(),anyInt())).thenReturn(SomeRepository);

    //calling MainClass method
    MainClass.someServiceMethod();
}

类C的getSomeData()方法返回NULL的ABC类对象,然后将其设置为另一个相同的类类型对象。 设置值后,由于ABC为NULL,我得到了NULLPointerException。 有人知道我要去哪里错吗?

您在编写模拟语句时未返回预期的对象

    @Service
public class C {
    @Autowired
    SomeRepository someRepository;
    public ResultClass getResult(string,string, int, int, List<String>,boolean){
        ABC returnSomeClassObject = someRepository.getSomeData(String,int,int);

        //Your return type should be ResultClass 
        // Where your return statement
        // What is ABC?
    }
}

@Test
MainClassTest {
    @MockBean
    SomeRepository someRepository;
    when(someRepository.getSomeData(anyString(),anyInt(),anyInt())).thenReturn(SomeRepository);
    // Why are you returning SomeRepository, This Should return object of ABC

@MockBean 
ABC mockResultClass
when(someRepository.getSomeData(anyString(),anyInt(),anyInt())).thenReturn(mockResultClass);

    //calling MainClass method
    MainClass.someServiceMethod();
}

您正在调用MainClass.someServiceMethod() ,后者依次调用C类的getResult() 。如果要测试Main类的someServiceMethod() ,则应该someServiceMethod() C类并在C类的getResult()上使用when-thenReturn。 由于这是单元测试,因此Autowired在这里不起作用,因此Main类中C c的实例将为null。 如下所示:

@MockBean
C c;
when(c.getResult(anyString(), anyString(),anyInt(),anyInt(), any(List.class), anyBoolean()).thenReturn(someResult);

c.getResult(string,string, int, int, List<String>,boolean);

因此,首先,我们需要明确您要进行的单元测试。 如果您要对someServiceMethod内的MainClass进行单元测试,则意味着您也不应同时测试someRepository的功能。 这个想法是,每个单元测试应该只测试一个代码单元。 因此,要做到这一点,我们需要使用存根作为替代,以替代您调用其他类拥有的方法时实际发生的情况。 然后,我们将只为someRepository.getSomeData()编写一个不同的单元测试,以确认它也按预期工作。 以这种方式,当稍后出现错误时,我们将确切知道遇到问题的位置。

我看到的另一个问题是C getResult()的返回类型显然不匹配。 该方法说它返回一个ResultClass ,但是当您调用getSomeData您期望一个ABC对象。 您要么省略了将对象转换回ResultClass的详细信息,要么就是一个错误。 除非您另有说明,否则我将假设前者。

考虑到这一点,让我们编写测试。 这是我编写测试的方式:

@RunWith(SpringRunner.class)
public class MainClassTest {

    @Mock
    C c;

    @InjectMocks
    MainClass mainClass;

    @Test
    public void testSomeServiceMethod {

        ResultClass resultClass = new ResultClass(); //relevant constructor details here, mockbean, etc. you get the idea

        //set any desired data for resultClass here

        Mockito.when(c.getResult(anyString(), anyString(), 
            anyInt(), anyInt(), any(List.class), anyBoolean()))
            .thenReturn(resultClass);

        ResultClass newResult = mainClass.someServiceMethod();

        //relevant test assertions here
    }
}

如您所见,我们正在测试中创建一个ResultClass ,并告诉Mockito在调用getResult时返回该值,而不是通常期望它返回的值。 尽管功能现在似乎有限,但由于我们仅测试MainClass而不是其余的方法调用,因此这是首选。

除此之外,我们可以(并且应该)对C getResultgetSomeData中的SomeRepository编写测试。 我将由您来编写这些测试。

编辑:不小心过早发布了,现在修复。

暂无
暂无

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

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