2012-01-25 22 views
8

Yansıma tabanlı bazı yöntemlerle dalga geçmeye çalışıyorum. EğerMocking Yansıma tabanlı çağrılar

public class TracerLog { 
    @AroundInvoke 
    public Object logCall(InvocationContext context) throws Exception { 
     Logger logger = new Logger(); 
     String message = "INFO: Invoking method - " 
       + context.getMethod().getName() + "() of Class - " 
       + context.getMethod().getDeclaringClass(); 

     logger.write(message); 
     return context.proceed(); 
    } 
} 

Testi

public class TracerLogTest { 

@Mock 
InvocationContext mockContext; 
@Mock 
Logger mockLogger; 
@InjectMocks 
private TracerLog cut = new TracerLog(); 

@BeforeMethod 
public void setup() { 
    MockitoAnnotations.initMocks(this); 
} 

@Test 
public void logCallTest() throws Exception { 
    when(mockContext.proceed()).thenReturn(true); 
    when(mockContext.getMethod().getDeclaringClass().getName()).thenReturn("someClass"); 
    cut.logCall(mockContext); 
    verify(mockContext).proceed(); 
} 

}

veya

@Test 
public void logCallTest() throws Exception { 
    when(mockContext.proceed()).thenReturn(true); 
    when(mockContext.getMethod().getName()).thenReturn("someMethod"); 
    when(mockContext.getMethod().getDeclaringClass().getName()).thenReturn("someClass"); 
    cut.logCall(mockContext); 
    verify(mockLogger).write(anyString()); 
    verify(mockContext).proceed(); 
} 

Fakat testler NullPointerException ile başarısız detaylarını, Testi altında

Class görebilirsiniz Aşağıda . Alaycı kavramlara karşı yanlış bir şey yaptığımı anlıyorum, ama ne olduğunu anlamıyorum. Biraz ışık tutabilir misiniz ve bana bu yöntemin nasıl test edilebileceğini gösterir misiniz?

Teşekkürler.

+0

Sahte nesnelerinizi ve test edilen nesneyi nasıl yaratıyorsunuz? Test metodunu değil, tüm test sınıfınızı yayınlayabilir misiniz? Teşekkürler. –

+0

@DavidWallace Sorunun tamamını kodun tamamını içerecek şekilde düzenledim. – Bala

cevap

17

Bir Method nesnesine ve Class nesnesine ihtiyacınız vardır. Yorumunuza göre, Mockito bir Yöntem ile alay edemez, bu yüzden gerçek bir tane gerekir. Bunu test etmedim, ama bunun işe yarayacağına inanıyorum. Onun yerine: Eğer edemedim rağmen

// any method will do, but here is an example of how to get one. 
Method testMethod = this.getClass().getMethod("logCallTest"); 

when(mockContext.getMethod()).thenReturn(testMethod); 

Açıkçası, getName() artık "birYöntem" döndürmez ve getDeclaringClass().getName() (örnekte) bu test sınıfının adını dönecek ama:

when(mockContext.getMethod().getName()).thenReturn("someMethod"); 
when(mockContext.getMethod().getDeclaringClass().getName()).thenReturn("someClass"); 

İhtiyacınız Ne döndüklerini seçtiler, geri döndükleri hâlâ belirleyicidir, bu yüzden ihtiyacınız olan her şeyi doğrulayabilmeniz gerekir. (Elbette, Metod nesnesinin kendisinde bir çağrının yapıldığını doğrulamanız veya doğrulamanız gerekiyorsa, hala sıkışmış olursanız.)

+0

Cevabınız için teşekkürler, ancak Mockito, bunun java.lang.reflect.Method ile dalga geçemeyeceğini veya casusluk yapamayacağından şikayetçidir. Bunu başarmanın başka yolları var mı? – Bala

+0

Gerçek bir Metod nesnesinin nasıl kullanılacağını göstermek için cevabımı düzenledim. Bu, sorunuzdaki basit örneklere değinmelidir, ancak yine de sınırlamalar vardır. – jhericks

+0

Öneriniz için teşekkürler, ancak mockContext.getMethod(). GetDeclaringClass() bu durumda çalışmayacak. – Bala

3

Evet, sorun şu ki, mockContext.getMethod() null değerini döndürecek. Yani bunu her çalıştırdığınızda, sonuçta bir şey arayın (getDeclaringClass() veya getName()), NPE alırsınız. Sahneyi kurduğunuzda muhtemelen RETURNS_DEEP_STUBS varsayılan yanıtını kullanmak istersiniz. Hile yapması gereken

gibi bir şey yapmalıdır.

+0

Merhaba David Çoğunlukla size katılıyorum. Ancak okuyucu için: Yöntem son sınıf, Mockito ile alay edilemez;) Ayrıca sahip olmadığınız türlerle alay etmenizi tavsiye etmem. – Brice

+0

Ah rahatsız ediyor. Brice haklı (genellikle bu şeyler hakkında). Mockito son sınıflarla dalga geçemeyeceğinden, orijinal posterin istediği şeyi yapmanın bir yolunu görmüyorum. Afedersiniz. –

+0

@Brice Eh, size katılıyorum, ancak InvocationContext bir son sınıf değil ve benim durumumda alay edilmek zorunda çünkü uygulama sunucusunun testim için çalışmasını istemiyorum. Bir yerlere yanlış mı gittim? – Bala