以下是JUnit测试,oneLoginAuthUtil
是Mocked。但Mockito.when
正在返回null
。 oneLoginAuthUtil.getMetaData
始终为null
。以下是代码 -
public void func() throws Exception {
StringBuilder b = new StringBuilder("test");
RequestContext context = new RequestContext();
Mockito.when(oneLoginAuthUtil.getMetaData(context, b)).thenReturn("abcdef");
ResponseEntity<Object> response = loginControllerImpl.handleGetMetaDataEndPointImpl(context);
}
public String getMetaData(RequestContext context, StringBuilder b) throws Exception {
Auth auth = getOneLoginAuthObject(context);
final Saml2Settings settings = auth.getSettings();
String metadata = settings.getSPMetadata();
List<String> errors = Saml2Settings.validateMetadata(metadata);
if (!errors.isEmpty()) {
b.append(errors.toString());
throw new SSOException("metadata_validation_error");
}
return metadata;
}
public ResponseEntity<Object> handleGetMetaDataEndPointImpl(RequestContext context) {
try {
StringBuilder b = new StringBuilder();
String metadata = oneLoginAuthUtil.getMetaData(context, b);
log.info(metadata);
return new ResponseEntity<>(metadata, new HttpHeaders(), HttpStatus.CREATED);
} catch (Exception e) {
return new ResponseEntity<>("<error>Exception: " + e.getMessage() + "</error>", new HttpHeaders(),
HttpStatus.CREATED);
}
}
但没有oneLoginAuthUtil.getMetaData
作为参数的StringBuilder
方法可以正常工作。
答案 0 :(得分:4)
返回null
因为当您使用特定实例作为参数模拟方法时,当且仅当测试时提供的参数等于您在模拟时提供的参数时,Mockito将返回映射的返回值。显然不是这样的。 Mockito没有匹配,所以它返回一个方法的默认值,该方法返回一个名为null
的模拟对象。
换句话说,Mockito.when(oneLoginAuthUtil.getMetaData(context, b))
等同于Mockito.when(oneLoginAuthUtil.getMetaData(Mockito.eq(context), Mockito.eq(b)))
,此处类StringBuilder
不会覆盖方法equals(Object obj)
,模拟时提供的实例不等于测试时提供的实例,因为它们不是同一个实例(依赖于equals(Object obj)
的默认实现时唯一可能是相同的),这样就可以得到这种行为。
因此,您应该使用Mockito.any(StringBuilder.class)
来匹配StringBuilder
类型的任何实例,以便实例不再需要相等,那么您的代码将是:
Mockito.when(
oneLoginAuthUtil.getMetaData(Mockito.eq(context), Mockito.any(StringBuilder.class))
).thenReturn("abcdef");
假设您的主要课程为LoginControllerImpl
并且其成员字段oneLoginAuthUtil
的类型为OneLoginAuthUtil
,您可以使用注释@InjectMocks
直接注入您的模拟键入OneLoginAuthUtil
,完整的代码将是:
@RunWith(MockitoJUnitRunner.class)
public class LoginControllerImplTest {
@Mock
private OneLoginAuthUtil oneLoginAuthUtil;
@InjectMocks
private LoginControllerImpl loginControllerImpl;
@Test
public void func() throws Exception {
RequestContext context = new RequestContext();
Mockito.when(
oneLoginAuthUtil.getMetaData(
Mockito.eq(context), Mockito.any(StringBuilder.class)
)
).thenReturn("abcdef");
ResponseEntity<Object> response
= loginControllerImpl.handleGetMetaDataEndPointImpl(context);
...
}
}
答案 1 :(得分:3)
StringBuilder
未实现equals()
或hashCode()
,因此无法像这样使用参数匹配。
问题实际上是你不应该将一个可变对象(例如StringBuilder
)传递给你的测试对象。为什么返回&#34;元数据&#34;要求您附加到范围之外的StringBuilder
吗?