在使用 mockito 调用服务类的嵌套方法时获取 NullPointerException



我正在为我的服务类编写 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() 方法返回 ABC 类对象,该对象为 NULL,后来设置为另一个相同的类类型对象。 设置值后,我得到 NULLPointerException,因为 ABC 是 NULL。 有人知道我哪里出错了吗?

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

@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 。你应该嘲笑C类,如果你的目的是测试MainsomeServiceMethod(),你应该嘲笑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);

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

我看到的另一个问题是CgetResult()的返回类型明显不匹配。该方法说它返回一个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编写测试,并在SomeRepositorygetSomeData。我会留给你来编写这些测试。

编辑:不小心发布得有点早,现在修复。

相关内容

  • 没有找到相关文章

最新更新