2013-03-24 15 views
11

JMockit 1.1 kullanıyorum ve tek yapmak istediğim özel bir yöntem çağırmak ve dönüş değerini test etmek. Ancak, bunun nasıl yapılacağını tam olarak anlamada sorun yaşıyorum JMockit De-Encapsulation örneğinden.Test sonucu için JMockit üzerinden özel bir yöntem çağırma

test etmek çalışıyorum yöntem bu sınıfta özel bir yöntemdir:

public class StringToTransaction { 
    private List<String> parseTransactionString(final String input) { 
     // .. processing 
     return resultList; 
    } 
} 

Ve benim test kod aşağıda belirtilmiştir.

@Test 
public void testParsingForCommas() { 
    final StringToTransaction tested = new StringToTransaction(); 
    final List<String> expected = new ArrayList<String>(); 
    // Add expected strings list here.. 
    new Expectations() { 
     { 
     invoke(tested, "parseTransactionString", "blah blah"); 
     returns(expected); 
     } 
    }; 
} 

Ve alıyorum hatadır: Sadece sonucu test .. ben sınıfını taklit istiyor sanmıyorum çünkü

java.lang.IllegalStateException: Missing invocation to mocked type at this point; please make sure such invocations appear only after the declaration of a suitable mock field or parameter

Belki, burada bütün API yanlış anlamış özel yöntemi çağırmak.

cevap

25

Bence bunu çok karmaşık yapıyorsunuz. Beklentiler bloğunu hiç kullanmamalısınız. Gerçek beklenen eşit olduğunu

Temelde
@Test 
public void testParsingForCommas() { 
    StringToTransaction tested = new StringToTransaction(); 
    List<String> expected = new ArrayList<String>(); 
    // Add expected strings list here.. 

    List<String> actual = Deencapsulation.invoke(tested, "parseTransactionString", "blah blah"); 
    assertEquals(expected, actual); 
} 

, Deencapsulation yoluyla özel bir yöntemi çağırmak ve test: Yapmanız gereken tek şey böyle bir şeydir. Tıpkı yöntemin herkese açık olması gibi. Hiçbir alay yapılmaz, bu yüzden Beklentiler bloğuna gerek yoktur.

+0

Merhaba @JeffOlson - hangi sınıf invoke() yöntemidir? Beklentilerde, invoke() bir korunan örnek yöntemidir. Ya da sadece java.lang.reflect.Method.invoke() kullanın ve tamamen JMockit'i göz ardı edin .. –

+0

Sonunda anladığım kadarıyla ... "Deencapsulation.invoke", teşekkürler @JeffOlson ve https: // gruplarında Rogerio'ya teşekkürler. google.com/d/msg/jmockit-users/oEgjW0DfmgU/3pEE1mjt1ncJ. –

+0

Evet, doğru. Daha açık olmamak için özür dilerim, ancak doğrudan (örneğin statik bir aktarım yoluyla) ilk örneğinizde 'invoke() 'yi kullandınız, böylece onu olduğu gibi bırakacağımı düşündüm. Gelecekte bunu okuyabilecek herkes için daha açık olmak için cevabımı güncelleyeceğim. –

0

Neden özel yöntemi doğrudan test etmek istiyorsunuz? Çoğu zaman API metotları, yani kamusal arayüz metotları, olarak test edilmiş ünitelerdir, özel usuller, dolaylı olarak bunlarla birlikte da test edilecektir. Özel yöntemler'dan beklenen yöntemlerle assert ifadelerini, genel yöntemlerle çağırdığınız yere koyabilirsiniz. Bu nedenle, başarısız olursa, özel yöntemle ilgili bir sorun olduğundan eminsiniz. Yani ayrı ayrı test etmenize gerek yok.

+0

Merhaba @Ankur, özür dilerim, ancak JMockit'in bu durumda nasıl doğru şekilde kullanılacağını içeren bir cevap arıyorum (veya yapıp yapmamam olsa bile). Özel bir yöntemi neden test etmemeli veya test etmem gerektiğini tartışmak istemiyorum. Kamu yöntemleriyle iddiaları kullanmanın başka bir yol olduğunu anlıyorum, ama burada çalışmak için uğraştığım şey bu değil. –

+0

Şuna bir göz atın: http://stackoverflow.com/questions/5729973/jmockit-two-mocked-instances-of-the-same-type –

+0

Biraz yoğun @Ankur olabilir ama nasıl yapamıyorum Bu sorunu benim sorunuma uygulayın. ** ** ** testinin ** başlatılmasından önce ** Beklentiler ** bloğu konulması bir derleme hatasıyla sonuçlanır: ** test edilmiş bir değişkene ** çözümlenemez. –

2

Bu noktada, JMockit'in bunun için kullanılıp kullanılamayacağını bilmiyorum. JMockit hakkında bilgi edinmek için bu alıştırmaya başladım (ve kodumu test et). JMockit'in bunun için kullanılamaması durumunda, bunun yerine yansımayı nasıl kullanabileceğimi buradan öğrenebilirsiniz. setAccessible(true) için

@Test 
public void testParsingForCommas() throws Exception { 
    StringToTransaction tested = new StringToTransaction(); 
    ArrayList<String> expected = new ArrayList<>(); 
    expected.add("Test"); 

    Method declaredMethod = 
     tested.getClass().getDeclaredMethod("parseTransactionString", 
       String.class); 
    declaredMethod.setAccessible(true); 
    Object actual = declaredMethod.invoke(tested, "blah blah"); 
    assertEquals(expected, actual); 
} 

çağrı Burada önemli olan ya da özel bir yöntemi çağrılırken invoke uçurma olacaktır.

declaredMethod.setAccessible(true); 

Ama neyin gerçekten havalı olduğunu bilmek mi istiyorsunuz? setAccessible(true)'u aramadıysanız, java.lang.StackOverflowError ile patlayacak! :)

İlgili konular