2013-03-26 23 views
5

kullanarak yeni bir sınıfın örneğini oluştururken bir özel durumla nasıl uğraşılır Bir yöntemde, alay etmek istediğim bir özel durum var.Mockito

Bir nesne mock.doSomething() kullanarak bir istisna atmak için alay etmeyi biliyorum, ancak bir sınıf kendi başına yeni bir örnek oluşturduğunda uzaktan bir istisna atmam gerekiyor.

transient Bicycle bike = null; 

public Bicycle getBicycle() { 
    if (bike == null) { 
     try { 
      bike = new Bicycle(this); 
     } catch (RemoteException ex) { 
      System.out.println("No bikes found"); 
     } 
    } 
    return bike; 
} 

ben try bloğundaki her şeyi alay etmek isterler, ama yeni bir sınıfın oluşmasını alay nasıl anlamıyorum, aşağıdaki satır belirli olması:

bike = new Bicycle(this); 

Ben gibi birçok farklı mockito testleri, denedim: Ben bu iradeyi anlamak rağmen

Bicycle b = mock(Bicycle.class); 
Mockito.doThrow(new RemoteException()).when(b = new Bicycle()); 

ve çalışmıyor, ben benzer bir şey yapmak istiyorum.

Ben mockito dokümanlar okudum ve yararlı bir şey bulamadı:

http://site.mockito.org/mockito/docs/current/org/mockito/Mockito.html

+0

olası yinelenen [JUnit testinde RemoteException atmak Mockito nasıl zorlanır] (http://stackoverflow.com/questions/15582395/how-to-force-mockito-to-throw-remoteexception-in-junit-test) –

+0

@ ChristofferHammarström Bu kesinlikle bir kopya değil. Önceki soruyu yazdım ve her ikisinden de iki farklı cevap arıyorum. –

cevap

3

Böyle durumlarda bir Mockito eklentisi PowerMock kullanabilirsiniz. Kurucuların alay edilmesine izin verir (bkz. https://code.google.com/p/powermock/wiki/MockConstructor).

@RunWith(PowerMockRunner.class) 
@PrepareForTest({ClassUnderTest.class, Bicycle.class}) 
public class ConstructorMockingTest 
{ 
    @Test 
    public void getBicycle() 
    { 
     ClassUnderTest tested = new ClassUnderTest(); 
     whenNew(Bicycle.class).withArguments(tested).thenThrow(new RemoteException()); 

     Bicycle bicycle = tested.getBicycle(); 

     assertNull(bicycle); 
    } 
} 

fazla örnek bulunabilir: Bu durumda

, aşağıdaki testi yazabiliriz https://code.google.com/p/powermock/source/browse/trunk/modules/module-test/mockito/junit4/src/test/java/samples/powermockito/junit4/whennew/WhenNewTest.java

ait
7

Sen sahte kurucular genelde gerekmez. Siz PowerMock gibi araçlarla yapabilirsiniz, ancak genellikle önermemenizi öneririm.

Şu anda, kodunuz yeni bir Bicycle oluşturulduğunda ne olacağını kontrol etmek istiyorsanız, aslında test edilebilir değildir. Bir Bicycle aslında karmaşık bir işlem mi inşa ediyor? Belki de bir bağımlılık olarak sınıfınıza geçirilebilen bir BicycleFactory istersiniz, örneğin - ve daha sonra ile BicycleFactory.createBicycle ya da ne adlandırırsanız alay edebilirsiniz.

Oluşturucular statik yöntemler gibidir - bunları kullandığınızda, aradığınız özel kodla sıkı sıkıya bağlısınız; PowerMock gibi yaklaşımlar olmadan diğer davranışları enjekte etmenin temiz bir yolu yoktur.

+0

Bunu açıklığa kavuşturduğumu sanmıyorum ama Bisiklet, şu anda bu yöntemin içinde bulunduğu başka bir sınıfın örneğidir.Yöntem, örneği alır, ancak boşsa, yeni bir tane oluşturmak istiyorum. Bunun bir şeyi değiştirip değiştirmeyeceğinden emin değilim? –

+0

@JohnVasiliou: Hayır, hiç de değil. Hala bir kurucu çağırıyorsunuz - ki bu temelde testlerde taklit edilebilecek bir şey değil. –

+0

Doğrudan bağımlılığın doğrudan gerçekleştirilmesi gereken doğru şey olduğu birçok gerçek dünya durumu vardır. Böyle bir örnek için, e-posta yoluyla bir bildirim göndermesi gereken bir iş hizmet sınıfı düşünün; Java, e-posta için iyi bilinen bir API'sıdır [Apache Commons Eposta] (http://commons.apache.org/proper/commons-email), normalde bir 'Email' alt sınıfı örneğini nerede (genellikle,' SimpleEmail'), Birkaç ayarlayıcı/toplayıcıyı çağır ve son olarak 'send()' yöntemini çağır. Basit, nesne yönelimli, * ve * ünite testine kolay. –

0

getBicycle() şimdi en az iki şey yapıyor. Bir Bicycle'u ("alır") alır ve bir Bicycle oluşturur. İdeal olarak bir yöntem ya da sınıf sadece bir şey yapmalı ve iyi yapmalı.

ayrı yöntem createBicycle() ya da ayrı ayrı BicycleFactory nesnenin yaratılmasına koyun ve bu dalga.