![](/img/trans.png)
[英]NullPointerException while invoking mocked method using Mockito
[英]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
getResult
和getSomeData
中的SomeRepository
编写测试。 我将由您来编写这些测试。
编辑:不小心过早发布了,现在修复。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.