2011-10-08 16 views
31

यूनिट टेस्ट में विधि आमंत्रणों को गिनने का सबसे अच्छा तरीका क्या है। क्या कोई परीक्षण ढांचा इसे अनुमति देता है?यूनिट परीक्षणों में विधि आमंत्रण की गणना

+0

आप आपको बस इतना करना कोशिश कर रहे हैं पर विस्तृत सकता है? क्या आप कोड कवरेज को मापने की कोशिश कर रहे हैं? प्रदर्शन? दक्षता? –

+0

वास्तव में नहीं। बस यह जांचना चाहते हैं कि जब मैं testXXX() परीक्षण विधि को कॉल करता हूं, तो कक्षा में उस विधि foo() को कम से कम N बार कहा जाता है। – user855

+0

क्या यह संभव नहीं है? मुझे पता है कि मॉकिंग फ्रेमवर्क मुझे मॉक ऑब्जेक्ट्स पर आमंत्रण संख्याओं पर जोर देने की अनुमति देता है।क्या वास्तविक वस्तुओं पर ऐसा करना संभव नहीं है? – user855

उत्तर

1

आपके पास कुछ विकल्प

1) कुछ विशेष कोड है जो समारोह में आमंत्रण मायने रखता जोड़े मिल गया है। यह काम करेगा, लेकिन यह एक अच्छा समाधान नहीं है।

2) आपके यूनिट परीक्षण चलाने के बाद, कोड कवरेज की जांच करें। अधिकांश कवरेज टूल इनवॉक्शन की गणना करेंगे लेकिन वे वास्तव में पोस्ट-प्रोसेसिंग के लिए डिज़ाइन किए गए हैं।

3) एक प्रोफाइलर का उपयोग करें। एक प्रोफाइलर आपको गिनने देगा कि फ़ंक्शन कितनी बार लागू किया जाता है। यह एक बहुत ही मैन्युअल प्रक्रिया है इसलिए यह वास्तव में यूनिट परीक्षण के लिए डिज़ाइन नहीं किया गया है।

एक बेहतर समाधान यह जांचना होगा कि आउटपुट आप अपेक्षा करते हैं कि यह आंतरिक रूप से कैसे काम करता है।

2

ऐसा लगता है कि आप test spy चाहते हैं। उदाहरण के लिए, Mockito.spy() देखें।

3

क्या तरीकों आप गणना करना चाहते हैं पर निर्भर करता है, तो आप एक परीक्षण config, एक @Before सलाह के साथ मिलान अपने वर्ग/पैकेज/विधि बना सकते हैं:

import org.aspectj.lang.annotation.Aspect; 
import org.aspectj.lang.annotation.Before; 
import org.aspectj.lang.annotation.Pointcut; 

@Aspect 
public class MethodCounterAspect { 

    private int counter = 0 // or inject the Counter object into this aspect 

    @Pointcut("execution(* com.sample.your.package.*.*(..))") 
    public void methodsToCount() {} 

    @Before("methodsToCount()") 
    public void execute() throws Throwable { 
     counter++; // or update the counter injected into this aspect.. 
    } 

    // get the counter 
} 

आप ऊपर या के माध्यम से वेनिला AspectJ या वसंत AOP उपयोग कर सकते हैं अगर आपको यह आसान लगता है तो एक्सएमएल कॉन्फ़िगरेशन।

यदि आपको आवश्यकता हो तो आप विभिन्न पॉइंटकट/पहलू बना सकते हैं।

+0

यदि आप केवल आमंत्रण की संख्या देखना चाहते हैं तो यह करने का तरीका है। यदि आप इनवॉक्शंस को सत्यापित करना चाहते हैं, तो नकली ढांचे आम तौर पर आपके लिए इस पैटर्न को दावे के साथ लपेटें। नकली संस्करण के लिए मेरा जवाब देखें। –

+0

सवाल यह है कि "यूनिट टेस्ट_ में विधि आमंत्रणों को गिनने का सबसे अच्छा तरीका क्या है"। उपर्युक्त आपको केवल ऐसा करने की अनुमति देगा => ** यूनिट/इंटीग्रेशन टेस्ट में विधि आवंटन की गणना ** बिना प्रदूषण परीक्षणों के। – tolitius

+0

मैं सहमत हूं, यही कारण है कि मैंने आपको वोट दिया। लेकिन टिप्पणियों में लेखक असली वस्तुओं बनाम नकली वस्तुओं के लिए आमंत्रण गणना पर जोर देने के बारे में पूछता है। यदि वह वास्तव में इनवोकेशन का परीक्षण करना चाहता है, तो उसे नकली पुस्तकालय का उपयोग करना चाहिए क्योंकि यही वह है जिसे वे बनाया गया है। –

40

ऐसा लगता है कि आप .expects (1) प्रकार विधियों का उपयोग करना चाह सकते हैं जो आम तौर पर प्रदान करते हैं।

, mockito का उपयोग करके आप एक सूची का परीक्षण और सत्यापित करने के लिए स्पष्ट 3 बार बुलाया गया था और जोड़ने इन पैरामीटर के साथ कम से कम एक बार बुलाया गया था चाहता था कर रहे थे अगर आप निम्न कार्य करें:

List mock = mock(List.class);   

someCodeThatInteractsWithMock();     

verify(mock, times(3)).clear(); 
verify(mock, atLeastOnce()).add(anyObject());  

(http://code.google.com/p/mockito/wiki/MockitoVSEasyMock से)

6

आप इंटरफ़ेस का उपयोग करके विधि आमंत्रण की संख्या गिनिटो में जवाब दे सकते हैं।

ConnectionPool mockedConnectionPool = mock(ConnectionPool.class); 

    final int[] counter = new int[1]; 

    when(mockedConnectionPool.getConnection()).then(new Answer<Connection>() { 

     @Override 
     public Connection answer(InvocationOnMock invocation) throws Throwable { 
      counter[0]++; 
      return conn; 
     } 

    }); 
    // some your code 

    assertTrue(counter[0] == 1); 
7

Mockito में आप कुछ इस तरह कर सकते हैं:

YourService serviceMock = Mockito.mock(YourService.class); 

// code using YourService 

// details of all invocations including methods and arguments 
Collection<Invocation> invocations = Mockito.mockingDetails(serviceMock).getInvocations(); 
// just a number of calls of any mock's methods 
int numberOfCalls = invocations.size(); 
+0

मुझे यह उपयोग करने के लिए सबसे सरल और सबसे प्रभावी तरीका माना गया है, जहां आपके पास मॉक ऑब्जेक्ट तक पहुंच है। – iZian

+0

धन्यवाद जैकब, यह भी अच्छा है क्योंकि यदि आप ऑब्जेक्ट का निरीक्षण करते हैं तो आप देख सकते हैं कि कहां और क्या कार्य कहलाए जा रहे हैं। – Stoffe

2

एक उदाहरण वर्ग एक एकल विधि "getRole (स्ट्रिंग उपयोगकर्ता)" जो एक भूमिका वापसी होगी के साथ "RoleRepository" को देखते हुए।

मान लीजिए कि आपने इस ऑब्जेक्ट को मॉक या जासूस के रूप में घोषित किया है और आप यह जांचना चाहते हैं कि विधि एक बार समय के लिए विधि (स्ट्रिंग) कहलाती है या नहीं।

आप की तरह कुछ करना होगा: Mockito.verify(roleRepository, Mockito.times(1)).getRole(Mockito.anyString());

import org.junit.Test; 
import org.junit.runner.RunWith; 
import org.mockito.Mockito; 
import org.mockito.Spy; 
import org.mockito.junit.MockitoJUnitRunner; 

@RunWith(MockitoJUnitRunner.class) 
public class RoleRepositoryTest { 

    @Spy 
    private RoleRepository roleRepository = new RoleRepository(); 

    @Test 
    public void test() { 
     roleRepository.getRole("toto"); 
     Mockito.verify(roleRepository, Mockito.times(1)).getRole(Mockito.anyString()); 
    } 

    public static class RoleRepository { 

     public String getRole(String user) { 
      return "MyRole"; 
     } 
    } 
}