2015-08-18 16 views
5

Bir alt sınıf tarafından gerçekleştirilen ancak soyut bir süper sınıftan miras alınan korumalı bir yöntemle alay etmek için Mockito veya PowerMock nasıl kullanılır? Başka bir deyişle, "doSomethingElse" alay ederken "doSomething" yöntemini test etmek istiyorum. Burada verilenSoyut sınıftan miras alınan korunan alt sınıf yöntemiyle nasıl dalga geçilir?

Özet süper sınıf

public abstract class TypeA { 

    public void doSomething() {  

     // Calls for subclass behavior 
     doSomethingElse();  
    } 

    protected abstract String doSomethingElse(); 

} 

Alt sınıf uygulaması

public class TypeB extends TypeA { 

    @Override 
    protected String doSomethingElse() { 
     return "this method needs to be mocked"; 
    } 

} 

Çözüm

Cevapları bir doğru Eğer ilgili sınıflar aynı pakette ise d çalışacaktır.

Farklı paketlerde varsa, bir seçenek PowerMock kullanıcısıdır. Aşağıdaki örnek benim için çalıştı. Elbette bunu yapmanın başka yolları da olabilir, bu işe yarar.

import static org.junit.Assert.assertEquals; 
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({ TypeB.class }) 
public class TestAbstract { 

    @Test 
    public void test_UsingPowerMock() throws Exception { 
     // Spy a subclass using PowerMock 
     TypeB b = PowerMockito.spy(new TypeB()); 
     String expected = "some value for mock"; 

     // Mock a method by its name using PowerMock again 
     PowerMockito.doReturn(expected).when(b, "doSomethingElse"); 

     // Calls the 
     String actual = b.doSomething(); 
     assertEquals(expected, actual);  

    } 
} 

Not: Java 5, JUnit 4.11, Mockito 1.9.0 ve PowerMock 1.4.12 kullanılarak yapılır Testler.

+1

Bu yaklaşım bana Java 8, JUnit 4.12 ve PowerMock 1.6.4 ile bir 'NullPointerException' veriyor. – Mack

cevap

5

Sen Mockito.CALLS_REAL_METHODS kullanabilirsiniz. Bu, sınıfın asıl yöntemlerini çağırır ve tüm soyut yöntemleri kendiniz alay edebilirsiniz.

TypeA typeA = mock(TypeA.class, Mockito.CALLS_REAL_METHODS); 
when(typeA.doSomethingElse()).thenReturn("Hello"); 
typeA.doSomething(); 

Veya bir ajanla TypeB doğrudan test etmek: sahte yöntemlerle için

TypeB typeB = spy(new TypeB()); 
when(typeB.doSomethingElse()).thenReturn("Hello"); 
typeB.doSomething(); 
+1

İlk seçenek başarısız oluyor, çünkü TypeA soyut. Seçenek 2, casus() ile çalışır, ancak bunu üretim koduma uyguladığımda, bana " türünden yöntemi görünmez" ifadesini verir. Nedenini anlamaya çalışıyorum. – BonanzaOne

+0

Aslında testiniz doğru, ancak farklı paketlerde bulunan sınıflarım var, bu yüzden daha önce bunu yapamadım. Korunduğunda yöntemler diğer paketlerden görünmez. – BonanzaOne

+0

İlk seçenek de mi çalışıyor?Hem Mockito 1.10.19 hem de son beta sürümü ile test ettim ve her ikisi de beklendiği gibi çalıştım. – mszalbach

3

Sen bunun için Mockito kullanmanızı öneririz şu şekilde

TypeA typA = Mockito.mock(TypeA.class, Mockito.CALLS_REAL_METHODS); 
when(typA.doSomethingElse()).thenReturn("doSomethingElse"); 
Assert.assertSomething(typeA.doSomething()); 
4

yılında Mockito kullanarak abtract sınıfını test edebilirsiniz: soyut yöntem alay zaman

// Create a new Mock 
final TypeA a = Mockito.mock(TypeA.class, Mockito.CALLS_REAL_METHODS); 

// Call the method 
a.doSomething(); 

// Now verify that our mocked class' method was called 
Mockito.verify(a, Mockito.times(1)).doSomethingElse(); 
+0

Çalışıyor, ancak üretim kodumda farklı paketlerde sınıfları olduğumu fark ettim. Korunan yöntemler o zaman görünür değil. – BonanzaOne

+0

Bu, onu sorun haline getirir. Olası bir çözüm, özel yöntemleri doğrulayabilen PowerMock kullanmaktır, afaik. Yine de hiç kullanmadım. –

2

soyut sınıflarda boşluk yarar bir döndürür:

MyAbstractClass abs = Mockito.mock(MyAbstractClass.class); 
Mockito.doNothing().when(abs).myMethod(arg1,arg2....)); 

Biz birlikte argümanlar yerine Gereksinimleri başına Mockito.anyString() vb.

İlgili konular