2012-04-19 90 views
1

對於單元測試目的,我想爲javax.security.auth.kerberos.KerberosTicket實例提供一個模擬。我試着用和的Mockito但PowerMockito都失敗,類似的消息:如何模擬KerberosTicket實例?

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及以下LinkageException @PrepareForTest註釋結果:

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}) public 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. 

是否有人有一個解決方案爲了這?

回答

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(...); 
+0

感謝您的答覆。 我已經添加了RunWith和PrepareForTest,但面對不同的錯誤,這就是爲什麼我開始刪除它們。重新添加它們會產生以下錯誤: java.lang.LinkageError:加載器約束違例:解析方法時「sun.security.jgss.krb5.Krb5Util.getTicketFromSubjectAndTgs(ILjava/lang/String; Ljava/lang/String; Ljava /郎/字符串; Ljava /安全/的AccessControlContext)Ljavax /安全/認證/的Kerberos/KerberosTicket;」當前類的類加載器(org/powermock/core/classloader/MockClassLoader的實例), – Marcel 2012-04-24 12:53:03

+0

org/epo/security/spnego/impl/KerberosUtilsTest,以及用於解析的類,sun/security的類加載器(實例)/jgss/krb5/Krb5Util,在簽名中使用類型爲javax/security/auth/kerberos/KerberosTicket的不同類對象 我已將測試代碼添加到問題中。 – Marcel 2012-04-24 12:53:51