1

出于单元测试的目的,我想为 javax.security.auth.kerberos.KerberosTicket 实例提供一个模拟。我尝试使用 Mockito 和 PowerMockito,但都以类似的消息失败:

org.mockito.exceptions.misusing.MissingMethodInvocationException: 
when() requires an argument which has to be 'a method call on a mock'.
For example:
    when(mock.getArticles()).thenReturn(articles);

Also, this error might show up because:
1. you stub either of: final/private/equals()/hashCode() methods.
   Those methods *cannot* be stubbed/verified.
2. inside when() you don't call method on mock but on some other object.

添加 @RunWith 和 @PrepareForTest 注释会导致以下 LinkageException:

java.lang.LinkageError:
  loader constraint violation: 
  when resolving method "sun.security.jgss.krb5.Krb5Util.getTicketFromSubjectAndTgs(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/security/AccessControlContext;)Ljavax/security/auth/kerberos/KerberosTicket;"
  the class loader (instance of org/powermock/core/classloader/MockClassLoader) of the current class, 
  org/epo/security/spnego/impl/KerberosUtilsTest, and the class loader (instance of <bootloader>) 
  for resolved class, sun/security/jgss/krb5/Krb5Util, have different Class objects 
  for the type javax/security/auth/kerberos/KerberosTicket used in the signature

我的测试类如下所示:

@RunWith(PowerMockRunner.class)

@PrepareForTest({KerberosTicket.class}) 公共类 KerberosUtilsTest {

@Test
public void testGetTicketFromSubjectAndTgs() throws LoginException, KrbException, IOException {
    PowerMockito.mockStatic(Krb5Util.class);
    KerberosTicket kerberosTicketMock = PowerMockito.mock(KerberosTicket.class);

    AccessControlContext controlContext = AccessController.getContext();

    // Causes the LinkageError to be thrown
    when(Krb5Util.getTicketFromSubjectAndTgs(-1, "test", "test", "test", controlContext)).thenReturn(
                kerberosTicketMock);

    KerberosTicket actual = new KerberosUtils().getTicketFromSubjectAndTgs(-1, "test", "test", "test",
                controlContext);

    assertEquals(kerberosTicketMock, actual);
}

搜索互联网显示,可以通过更改注释来修复 LinkageError:

@PowerMockIgnore({"sun.security.jgss.krb5.Krb5Util", "javax.security.auth.kerberos.KerberosTicket"})
@PrepareForTest({KerberosUtils.class})
@RunWith(PowerMockRunner.class)

运行这个让我回到第一方:

org.mockito.exceptions.misusing.MissingMethodInvocationException: 
when() requires an argument which has to be 'a method call on a mock'.
For example:
    when(mock.getArticles()).thenReturn(articles);

Also, this error might show up because:
1. you stub either of: final/private/equals()/hashCode() methods.
   Those methods *cannot* be stubbed/verified.
2. inside when() you don't call method on mock but on some other object.

有人对此有解决方案吗?

4

1 回答 1

1

的大多数方法KerberosTicket都是final,但 PowerMockito 应该能够模拟它们。

不要忘记按照 PowerMockito 的要求注释您的测试类以模拟final方法

@RunWith(PowerMockRunner.class)
@PrepareForTest(KerberosTicket.class)

并在测试中使用PowerMockito而不是Mockito

KerberosTicket mock = PowerMockito.mock(KerberosTicket.class);
PowerMockit.when(mock.getAuthTime().thenReturn(...);
于 2012-04-19T14:40:21.123 回答