2011-11-08 16 views
23

olarak adlandırılıyor. JNDI çağrısı yapan özel bir yöntemle alay etmeye çalışıyorum. Bu yöntem bir birim testinden çağrıldığında, bir istisna atar. Test amaçlı olarak bu yöntemle uğraşmak istiyorum. sample code from another questions answer'u kullandım ve test geçerken, temel yöntem hala çağrılıyor gibi görünüyor. doTheGamble() yöntemine System.err.println() ekledim ve konsoluma yazdırılıyor.PowerMock ile özel bir yöntem kullandı, ancak temel yöntem yine de

İlk assertThat'u açıklarsam, test başarılı olur. ? :(benim çalışma alanı JNDI desteklemediği

Yani, özel bir yöntem dışarı alay ediyorsun nasıl çağrılmadığı böylece?

import static org.hamcrest.core.Is.is; 
import static org.junit.Assert.assertThat; 
import static org.mockito.Matchers.anyInt; 
import static org.mockito.Matchers.anyString; 
import static org.powermock.api.mockito.PowerMockito.when; 
import static org.powermock.api.support.membermodification.MemberMatcher.method; 

import java.util.Random; 

import org.junit.Test; 
import org.junit.runner.RunWith; 
import org.powermock.api.mockito.PowerMockito; 
import org.powermock.core.classloader.annotations.PrepareForTest; 
import org.powermock.modules.junit4.PowerMockRunner; 

@RunWith(PowerMockRunner.class) 
@PrepareForTest(CodeWithPrivateMethod.class) 
public class PowerMock_Test { 

    static boolean gambleCalled = false; 

    @Test(expected = RuntimeException.class) 
    public void when_gambling_is_true_then_always_explode() throws Exception { 
     CodeWithPrivateMethod spy = PowerMockito.spy(new CodeWithPrivateMethod()); 

     when(spy, method(CodeWithPrivateMethod.class, "doTheGamble", String.class, int.class)) 
       .withArguments(anyString(), anyInt()) 
       .thenReturn(true); 

/* 1 */ assertThat(PowerMock_Test.gambleCalled, is(false)); 
     spy.meaningfulPublicApi(); 
/* 2 */ assertThat(PowerMock_Test.gambleCalled, is(false)); 
    } 
} 


class CodeWithPrivateMethod { 

    public void meaningfulPublicApi() { 
     if (doTheGamble("Whatever", 1 << 3)) { 
      throw new RuntimeException("boom"); 
     } 
    } 

    private boolean doTheGamble(String whatever, int binary) { 
     Random random = new Random(System.nanoTime()); 
     boolean gamble = random.nextBoolean(); 

     System.err.println("\n>>> GAMBLE CALLED <<<\n"); 
     PowerMock_Test.gambleCalled = true; 

     return gamble; 
    } 
} 

anlaşılır, sadece üretim ortamı

yapar^

% ı sahte bir nesne oluşturmak için tüm kütüphane, JUnit 4.10, Mockito 1.8.5, hamcrest 1.1, Javassist 3.15.0 ve PowerMock 1.4.10.

cevap

29

:

@RunWith(PowerMockRunner.class) 
// We prepare PartialMockClass for test because it's final or we need to mock private or static methods 
@PrepareForTest(PartialMockClass.class) 
public class YourTestCase { 
@Test 
public void privatePartialMockingWithPowerMock() {   
    PartialMockClass classUnderTest = PowerMockito.spy(new PartialMockClass()); 

    // use PowerMockito to set up your expectation 
    PowerMockito.doReturn(value).when(classUnderTest, "methodToMock", "parameter1"); 

    // execute your test 
    classUnderTest.execute(); 

    // Use PowerMockito.verify() to verify result 
    PowerMockito.verifyPrivate(classUnderTest, times(2)).invoke("methodToMock", "parameter1"); 
} 

Yani koduna bu uygulama, bunu olabileceğini düşünüyorum:

@RunWith(PowerMockRunner.class) 
@PrepareForTest(CodeWithPrivateMethod.class) 
public class PowerMock_Test { 
    @Test(expected = RuntimeException.class) 
    public void when_gambling_is_true_then_always_explode() throws Exception { 
     CodeWithPrivateMethod spy = PowerMockito.spy(new CodeWithPrivateMethod()); 

     PowerMockito.doReturn(true).when(spy, "doTheGamble", anyString(), anyInt()); 


/* 1 */ PowerMockito.verifyPrivate(spy, times(0)).invoke("doTheGamble", anyString(), anyInt());    
     spy.meaningfulPublicApi(); 
/* 2 */ PowerMockito.verifyPrivate(spy, times(2)).invoke("doTheGamble", anyString(), anyInt());    
    } 
} 

sadece o editörü burada kodlanmış. Hiçbir test çalıştırılmamıştır ve bu kodun işlenmesinde hiçbir hataya zarar verilmemiştir.

+8

+1. Çok önemsiyorum;) – Guillaume

+0

@Mike Neden doReturn (true) .when (casus, "doTheGamble", anyString(), anyInt()); 'ancak 'doReturn (true) .when (casus) yöntem, (CodeWithPrivateMethod.class, "doTheGamble", String.class, int.class)) .withArguments (anyString(), anyInt()); bir 'IllegalArgumentException 'in sonuçları: argüman mismatch'? İkincisi, örnek tarzına ve en azından eşdeğer olmasına rağmen daha fazla işe yaramaz ama işe yaramaz. – ArtB

+0

Gerçekten yapamam özür dilerim. Mockito/PowerMock'a kendim göreceli olarak yeniyim ... Daha önce hiç bu tarz bir kod yazmayı denemedim ('.Arşiv (...)'). – Mike

0

Eğer spy kullanmak son sürümlerini kullanıyorum, onun gerçek bir yarım destekli nesnesi. spy'dan kurtulmak için. saf sahte nesnede çalışın. PowerMock Private Method Example itibaren

+1

yüzden bu bir seçenek değildir. Hataların zarar görmemesi için – ArtB

1

ArtB,

emin kodunuzu çalışmıyor musunuz (veya) burada bir şey eksik? Sadece şu biriyle Mike önerdi yol senin yöntem beklenti yerini ve iyi çalışıyor: Ben Powermockito kullanılan ancak daha önce Mockito çok hiç kullanılmamış

PowerMockito.doReturn(true).when(spy, 
       method(CodeWithPrivateMethod.class, "doTheGamble", String.class, int.class)) 
       .withArguments(anyString(), anyInt()); 

.

+0

Evet, eminim ki işe koyulduktan sonra bir miktar çıktı elde edeceğim. – ArtB

2

ArtB,

Sadece benim Eclipse IDE çalışıyor tam kodu yapıştırmadan. Son yazımda söylediğim beklentiyi değiştirdim. İyi şanslar. Ben casusluk am sınıfın uygulanması test çalışıyorum

import static org.hamcrest.core.Is.is; 
import static org.junit.Assert.assertThat; 
import static org.mockito.Matchers.anyInt; 
import static org.mockito.Matchers.anyString; 
import static org.powermock.api.support.membermodification.MemberMatcher.method; 

import java.util.Random; 

import org.junit.Test; 
import org.junit.runner.RunWith; 
import org.powermock.api.mockito.PowerMockito; 
import org.powermock.core.classloader.annotations.PrepareForTest; 
import org.powermock.modules.junit4.PowerMockRunner; 

@RunWith(PowerMockRunner.class) 
@PrepareForTest(CodeWithPrivateMethod.class) 
public class PowerMock_Test { 

    static boolean gambleCalled = false; 

    @Test(expected = RuntimeException.class) 
    public void when_gambling_is_true_then_always_explode() throws Exception { 
     CodeWithPrivateMethod spy = PowerMockito.spy(new CodeWithPrivateMethod()); 

//  PowerMockito.doReturn(true).when(spy, "doTheGamble", anyString(), anyInt()); 

     PowerMockito.doReturn(true).when(spy, 
       method(CodeWithPrivateMethod.class, "doTheGamble", String.class, int.class)) 
       .withArguments(anyString(), anyInt()); 

     assertThat(PowerMock_Test.gambleCalled, is(false)); 
     spy.meaningfulPublicApi(); 
     assertThat(PowerMock_Test.gambleCalled, is(false)); 
    } 
} 


class CodeWithPrivateMethod { 

    public void meaningfulPublicApi() { 
     if (doTheGamble("Whatever", 1 << 3)) { 
      throw new RuntimeException("boom"); 
     } 
    } 

    private boolean doTheGamble(String whatever, int binary) { 
     Random random = new Random(System.nanoTime()); 
     boolean gamble = random.nextBoolean(); 

     System.err.println("\n>>> GAMBLE CALLED <<<\n"); 
     PowerMock_Test.gambleCalled = true; 

     return gamble; 
    } 
} 
İlgili konular