ইনক্রেকশন মকিতো মককে একটি স্প্রিং শিমের মধ্যে


284

আমি জুনিটের সাথে ইউনিট পরীক্ষার উদ্দেশ্যে একটি মকিতো মক বস্তুকে একটি স্প্রিং (3+) শিমের মধ্যে ইনজেকশন করতে চাই। আমার শিম নির্ভরতা বর্তমানে @Autowiredবেসরকারী সদস্য ক্ষেত্রগুলিতে টিকাটি ব্যবহার করে ইনজেকশন করা হয় ।

আমি ব্যবহারের বিষয়টি বিবেচনা করেছি ReflectionTestUtils.setFieldতবে শিমের দৃষ্টান্তটি যে আমি ইনজেকশন করতে চাই তা আসলে প্রক্সি এবং তাই লক্ষ্য শ্রেণীর ব্যক্তিগত সদস্য ক্ষেত্রগুলি ঘোষণা করে না। আমি নির্ভরতার জন্য একটি পাবলিক সেটার তৈরি করতে চাই না কারণ আমি পরীক্ষার উদ্দেশ্যে বিশুদ্ধরূপে আমার ইন্টারফেসটি সংশোধন করব।

আমি স্প্রিং সম্প্রদায় দ্বারা প্রদত্ত কিছু পরামর্শ অনুসরণ করেছি তবে উপহাসটি তৈরি হয় না এবং অটো-ওয়্যারিং ব্যর্থ হয়:

<bean id="dao" class="org.mockito.Mockito" factory-method="mock">
    <constructor-arg value="com.package.Dao" />
</bean>

আমি বর্তমানে যে ত্রুটিটির মুখোমুখি হয়েছি তা হ'ল:

...
Caused by: org...NoSuchBeanDefinitionException:
    No matching bean of type [com.package.Dao] found for dependency:
    expected at least 1 bean which qualifies as autowire candidate for this dependency.
    Dependency annotations: {
        @org...Autowired(required=true),
        @org...Qualifier(value=dao)
    }
at org...DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(D...y.java:901)
at org...DefaultListableBeanFactory.doResolveDependency(D...y.java:770)

যদি আমি constructor-argমানটিকে অকার্যকর কিছুতে সেট করি তবে অ্যাপ্লিকেশন প্রসঙ্গটি শুরু করার সময় কোনও ত্রুটি ঘটবে না।


4
: দয়া করে এই ক্ষুদ্র সামান্য জীব কটাক্ষপাত করা bitbucket.org/kubek2k/springockito/wiki/Home
kubek2k

এটি একটি খুব পরিষ্কার পদ্ধতির - আমি এটি পছন্দ করি!
9:59 টেবট

2
আপনি আমাকে স্প্রিংকিটো-টিকাতে পেয়েছিলেন।
yihtserns


2
তাদের জন্য বসন্ত ৪. * ব্যবহার করছে, ২০১৫ সালের জানুয়ারি পর্যন্ত এটি সর্বশেষ বসন্তের মকিতো সংস্করণের সাথে কাজ করছে বলে মনে হয় না এবং প্রকল্পটি নিষ্ক্রিয় বলে মনে হয়।
মুরালি

উত্তর:


130

সবচেয়ে ভাল উপায়:

<bean id="dao" class="org.mockito.Mockito" factory-method="mock"> 
    <constructor-arg value="com.package.Dao" /> 
</bean> 

আপডেট
প্রাসঙ্গিক ফাইলটিতে এই মকটি অবশ্যই স্বনির্ধারিত ক্ষেত্রের উপর নির্ভর করে ঘোষণা করা হওয়ার আগে তালিকাবদ্ধ থাকতে হবে।


আমি একটি ত্রুটি পেয়েছি: "নাম 'মকিতো' দিয়ে শিম তৈরিতে ত্রুটি: শিমের সংজ্ঞা বিমূর্ত"
tttppp

4
@amra সঠিক নয়: অবজেক্ট এই ক্ষেত্রে ফিরে ধরণ আভাসিত করা বসন্ত dosn't ... stackoverflow.com/q/6976421/306488
lisak

7
কেন জানি না কেন এই উত্তরটি এত বেশি আপলোড করা হয়েছে, ফলস শিমটি স্বতঃশক্ত হয়ে উঠতে পারে না কারণ এতে ভুল টাইপ রয়েছে।
আজেরোল

4
কনটেক্সট ফাইলে এটি প্রথমে তালিকাভুক্ত করা থাকলে এটি স্বয়ংক্রিয় করা যাবে (কোনও স্বায়ত্তশাসিত ক্ষেত্র যা তার উপর নির্ভর করবে তা ঘোষণার আগে)
রায়ান ওয়ালস

3
বসন্ত ৩.২ হিসাবে, মটরশুটির ক্রমটি এখন আর গুরুত্ব দেয় না। এই ব্লগ পোস্টে "জেনেরিক ফ্যাক্টরি পদ্ধতি" শিরোনামে বিভাগটি দেখুন: বসন্ত.io
রায়ান ওয়ালস

110
@InjectMocks
private MyTestObject testObject;

@Mock
private MyDependentObject mockedObject;

@Before
public void setup() {
        MockitoAnnotations.initMocks(this);
}

এটি পরীক্ষার শ্রেণিতে কোনও উপহাসকৃত বস্তুকে ইনজেক্ট করবে। এক্ষেত্রে এটি টেস্টবজেক্টে বিদ্রূপযুক্ত অবজেক্টটি ইনজেক্ট করবে। এটি উপরে উল্লিখিত ছিল তবে কোডটি এখানে।


1
আমি কীভাবে একটি নির্দিষ্ট পদ্ধতিতে স্ট্যাব করব mockedObject?
জিম হোল্ডেন

@ টিনাচর যখন (মস্কোডবজেক্ট.এক্সেকিউট) ।থেন রিটার্ন (অবজেক্টো রিটার্ন); আপনি এটি আগে পদ্ধতিতে বা আপনার পরীক্ষার পদ্ধতির ভিতরে রাখতে পারেন।
chaostheory

40
এফওয়াইআই: আমি যদি মাই টেস্টঅবজেক্টে আংশিক অটোয়ারিং এবং আংশিক উপহাস করতে চাই তবে এই পদ্ধতির কাজ হবে না।
রকসজ্জা

9
আমি কেন জানি না কেন এটি বেশি ভোট দেওয়া হয় না। যদি আমি এক্সএমএলযুক্ত আর কোনও উত্তর দেখতে পাই তবে আমি ছুড়ে যাচ্ছি।
MarkOfHall

3
কেন তুমি ব্যবহার করবেন না Mockito.spy(...)এই mockedObjectপরিবর্তে? এবং তারপরে when(mockedObject.execute).thenReturn(objToReturn)বা ব্যবহার করুন doReturn(objToReturn).when(mockedObject).execute()। দ্বিতীয়টি বাস্তব পদ্ধতিটি গ্রহণ করবেন না। আপনি Mockito.doCallRealMethod()ডকুমেন্টেশনও চেক করতে পারেন
টমাসজ প্রিজিবিস্কি

63

আমার কাছে স্প্রিং জাভা কনফিগার এবং মকিতো ব্যবহার করে খুব সহজ সমাধান রয়েছে:

@Configuration
public class TestConfig {

    @Mock BeanA beanA;
    @Mock BeanB beanB;

    public TestConfig() {
        MockitoAnnotations.initMocks(this); //This is a key
    }

    //You basically generate getters and add @Bean annotation everywhere
    @Bean
    public BeanA getBeanA() {
        return beanA;
    }

    @Bean
    public BeanB getBeanB() {
        return beanB;
    }
}

4
এই পদ্ধতির সাথে কোনও কারণে, বসন্ত যাইহোক প্রকৃত শিমটি তৈরি করার চেষ্টা করে (উপহাসের পরিবর্তে) এবং সেটির উপরে চাপ দেয় ... আমি কী ভুল করছি?
ড্যানিয়েল গ্রাসসেকেক

1
আমার একই সমস্যা আছে
করবকো অ্যালেক্স

3
বসন্ত নয় বরং মকিতো যদি আপনি কোনও শ্রেণি উপহাস করছেন তবে একটি আসল বিনকে তদন্ত করার চেষ্টা করে। যদি আপনার কোনও মটরশুটি থাকে যা পরীক্ষায় ঠাট্টা-বিদ্রূপ করতে হয় তবে সেগুলি একটি ইন্টারফেসের বাস্তবায়ন হওয়া উচিত এবং সেই ইন্টারফেসের মাধ্যমে ইঞ্জেকশন করা উচিত। তারপরে আপনি যদি ইন্টারফেসটিকে (ক্লাসের পরিবর্তে) উপহাস করে থাকেন তবে মকিতো সেই শ্রেণিকে ইনস্ট্যান্ট করার চেষ্টা করবে না।
ড্যানিয়েল গ্রাসস্কেক

7
আসলকথা কি? কেন টীকাগুলি ক্ষেত্র এবং কনস্ট্রাক্টর যুক্ত করবেন initMocks? শুধু return Mockito.mock(BeanA.class)ভিতরে না কেন getBeanA? এই উপায় এটি সহজ এবং কোড কম আছে। আমি কী মিস করছি?
ওলেগ

1
@ ওলগ মনে হচ্ছে আপনার নিজের সমাধান রয়েছে যা সম্ভবত আপনার উত্তর হিসাবে পোস্ট করা উচিত, যাতে সম্প্রদায় এটিতে ভোট দিতে পারে।
দাউদ ইবনে কেরেম

48

প্রদত্ত:

@Service
public class MyService {
    @Autowired
    private MyDAO myDAO;

    // etc
}

আপনার অটোওয়াইরিংয়ের মাধ্যমে লোড হওয়া ক্লাসটি থাকতে পারে, মকিতোর সাথে নির্ভরশীলতা উপহাস করুন এবং তারপরে পরীক্ষায় শ্রেণিতে মকটি ইনজেকশনের জন্য স্প্রিংয়ের রিফ্লেকশন টেস্টUtils ব্যবহার করুন।

@ContextConfiguration(classes = { MvcConfiguration.class })
@RunWith(SpringJUnit4ClassRunner.class)
public class MyServiceTest {
    @Autowired
    private MyService myService;

    private MyDAO myDAOMock;

    @Before
    public void before() {
        myDAOMock = Mockito.mock(MyDAO.class);
        ReflectionTestUtils.setField(myService, "myDAO", myDAOMock);
    }

    // etc
}

দয়া করে নোট করুন যে স্প্রিং ৪.৩.১ এর আগে এই পদ্ধতিটি প্রক্সি ( যা উদাহরণস্বরূপ @Transactional, বা বর্ণিত Cacheable) এর পিছনে পরিষেবাগুলির সাথে কাজ করবে না । এটি এসপিআর -14050 দ্বারা স্থির করা হয়েছে

পূর্ববর্তী সংস্করণগুলির জন্য, একটি সমাধানটি এখানে বর্ণিত হিসাবে প্রক্সিটি মোড়ক করা হয়: লেনদেনের টীকাগুলি পরিষেবাগুলি উপহাস করা এড়ানো হয় (এটি ReflectionTestUtils.setFieldএখন ডিফল্টরূপে কী করে)


ডাবল @ রুনউইথ (স্প্রিংজউইনিট 4 ক্লাসরুনার.ক্লাস) এবং আমি পরীক্ষার ক্লাসের জন্য একই টিকা (একই রানার) ব্যবহার করি তবে ধন্যবাদ এই পদ্ধতিটি আমার পক্ষে কাজ করে, ধন্যবাদ।
ব্যবহারকারী 1317422

1
"অনুগ্রহ করে নোট করুন যে বসন্তের ৪.৩.১ এর আগে এই পদ্ধতিটি কোনও প্রক্সি (পিছনে @ ট্রান্সজেকশনাল, বা ক্যাশেবল দ্বারা টীকায়িত) হিসাবে কাজ করবে না SP এটি এসপিআর -১০৫০ দ্বারা ঠিক করা হয়েছে"। আমি ঠিক এই ইস্যুটিতে দৌড়েছি এবং এই শব্দগুলি চিহ্নিত না করা পর্যন্ত কোনও ক্লু পাইনি। অনেক ধন্যবাদ!
স্নোফক্স

1
আপনি যখন কোনও সম্পূর্ণ অ্যাপ্লিকেশন প্রসঙ্গটি আপ করেছেন এবং পরীক্ষার উদ্দেশ্যে, আপনার প্রসঙ্গে একটি এলোমেলো মটরশুটিতে একটি মক ইনজেকশন করতে চাইলে এই সমাধানটি হ্যান্ডেল করে। মডিউল পরীক্ষায় অন্য মডিউলগুলিতে REST কল এড়ানোর জন্য আমি একটি জাল ক্লায়েন্ট শিমকে উপহাস করার জন্য এই উত্তরটি ব্যবহার করেছি। আমি কেবল তখনই কাজ করার জন্য ইনজেকমক টিকা পেয়েছিলাম যখন আপনি কোনও বিনের মধ্যে শঙ্কাগুলি ইনজেকশন দিচ্ছেন যা আপনি পরীক্ষা করতে চলেছেন, স্প্রিং অ্যাপ্লিকেশন কনফিগারেশন দ্বারা নির্মিত শিমের মধ্যে নয়।
আন্দ্রে লন্ডগ্রেন

1
প্রায় পুরো দিনই প্রসঙ্গটি পুনরায় সেট না করেই @ মকবিয়ানকে কাজ করার চেষ্টা করার চেষ্টা করছে এবং তারপরে আমি এই মণিটি পেরিয়ে এসেছি। হুবহু আমার যা প্রয়োজন, চিয়ারস।
ম্যাট আর

কাজ করে, যদিও সাবধান যে প্রতিস্থাপিত ক্ষেত্রটি ক্যাশিংয়ের কারণে পুনরায় সেট না হতে পারে এবং কিছু সম্পর্কযুক্ত পরীক্ষাগুলি ভেঙে যেতে পারে। উদাহরণস্বরূপ, আমার পরীক্ষায় আমি পাসওয়ার্ড এনকোডারকে একটি মক দিয়ে প্রতিস্থাপন করেছি এবং অনুমোদনের ব্যর্থতার কারণে কয়েকটি অন্যান্য পরীক্ষাগুলি ভেঙে গেছে।
অ্যালেক্সটসিল

36

আপনি যদি স্প্রিং বুট ১.৪ ব্যবহার করেন তবে এটি করার দুর্দান্ত উপায় রয়েছে। @SpringBootTestআপনার ক্লাসে এবং @MockBeanমাঠে কেবল নতুন ব্র্যান্ড ব্যবহার করুন এবং স্প্রিং বুট এই ধরণের একটি উপহাস তৈরি করবে এবং এটি এটিকে প্রসঙ্গে ইনজেক্ট করবে (মূলটি ইঞ্জেকশন করার পরিবর্তে):

@RunWith(SpringRunner.class)
@SpringBootTest
public class MyTests {

    @MockBean
    private RemoteService remoteService;

    @Autowired
    private Reverser reverser;

    @Test
    public void exampleTest() {
        // RemoteService has been injected into the reverser bean
        given(this.remoteService.someCall()).willReturn("mock");
        String reverse = reverser.reverseSomeCall();
        assertThat(reverse).isEqualTo("kcom");
    }

}

অন্যদিকে, আপনি যদি স্প্রিং বুট ব্যবহার না করে থাকেন বা আপনি পূর্ববর্তী সংস্করণ ব্যবহার করছেন, আপনাকে আরও কিছু কাজ করতে হবে:

এমন একটি @Configurationশিম তৈরি করুন যা আপনার উপহাসকে বসন্তের প্রসঙ্গে সংযুক্ত করে:

@Configuration
@Profile("useMocks")
public class MockConfigurer {

    @Bean
    @Primary
    public MyBean myBeanSpy() {
        return mock(MyBean.class);
    }
}

ব্যবহার @Primaryটীকাটি আপনি বসন্তকে বলছেন যে কোনও কোয়ালিফায়ার নির্দিষ্ট না করা থাকলে এই বিনের অগ্রাধিকার রয়েছে।

কোন ক্লাসটি @Profile("useMocks")মক ব্যবহার করবে এবং কোনটি আসল শিমটি ব্যবহার করবে তা নিয়ন্ত্রণ করার জন্য আপনি ক্লাসটি বেনিফিট করেছেন তা নিশ্চিত করুন ।

শেষ পর্যন্ত, আপনার পরীক্ষায়, userMocksপ্রোফাইল সক্রিয় করুন :

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = {Application.class})
@WebIntegrationTest
@ActiveProfiles(profiles={"useMocks"})
public class YourIntegrationTestIT {

    @Inject
    private MyBean myBean; //It will be the mock!


    @Test
    public void test() {
        ....
    }
}

আপনি যদি মক ব্যবহার করতে না চান তবে আসল বিন, কেবল useMocksপ্রোফাইল সক্রিয় করবেন না :

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = {Application.class})
@WebIntegrationTest
public class AnotherIntegrationTestIT {

    @Inject
    private MyBean myBean; //It will be the real implementation!


    @Test
    public void test() {
        ....
    }
}

5
এই উত্তরটি শীর্ষে যেতে হবে - @ বসন্ত বুটে মকবিয়ান সমর্থনটি বসন্ত-বুট ছাড়াই ব্যবহার করা যেতে পারে। আপনি কেবল ইউনিট পরীক্ষায় এটি ব্যবহার করতে পারেন তাই এটি সমস্ত বসন্ত অ্যাপ্লিকেশনের জন্য কাজ করে!
বেডরিন

2
@ প্রোফাইলে টীকাগুলি আপনি বিনের সংজ্ঞা পদ্ধতিতেও সেট করতে পারেন, আলাদা কনফিগারেশন ক্লাস তৈরি এড়াতে
মার্সিন

দুর্দান্ত উত্তর! এটি আমার পুরানো-স্কুল web.xmlএবং এ্যানোটেশন কনফিগওয়েব অ্যাপ্লিকেশনস কনটেক্সট সেটআপের সাথে কাজ করার জন্য আমি কয়েকটি পরিবর্তন করেছি । ব্যবহার ছিল @WebAppConfigurationপরিবর্তে @WebIntegrationTestএবং @ContextHierarchyসঙ্গে @ContextConfigurationপরিবর্তে @SpringApplicationConfiguration
ইউটিএফ_অর_দেথ

আমাকে @Primaryআমার মামলার জন্য টীকাটি যুক্ত করতে হয়েছিল, যেহেতু @PostConstructআমি যে ব্যঙ্গ করতে চাইছিলাম তার ভিতরে একটি ব্যর্থ কল হয়েছিল , তবে @PostConstructআমার মকের আগে শিমটি তৈরি করা হয়েছিল যাতে এটি মোকটিকে ব্যবহার না করে (আমি যোগ না করা পর্যন্ত @Primary)।
হেল্লে

19

1.8.3 থেকে মকিতো রয়েছে @InjectMocks- এটি অবিশ্বাস্যভাবে কার্যকর। আমার JUnit পরীক্ষা হয় এবং আমি বিল্ড যে বস্তু সন্তুষ্ট সব বর্গ জন্য নির্ভরতা পরীক্ষা করা হচ্ছে, যা সব ইনজেকশনের হয় যখন ব্যক্তিগত সদস্যের সঙ্গে সটীক হয়@RunWithMockitoJUnitRunner@Mock@InjectMocks

আমি@RunWithSpringJUnit4Runner ইন্টিগ্রেশন পরীক্ষার জন্য শুধুমাত্র এখন।

আমি নোট করব যে এটি List<T>বসন্তের মতো একইভাবে ইনজেক্ট করতে সক্ষম হবে বলে মনে হচ্ছে না । এটি কেবল এমন মক অবজেক্টের জন্য অনুসন্ধান করে যা সন্তুষ্ট করে Listএবং মক অবজেক্টগুলির একটি তালিকা ইনজেক্ট করবে না। আমার পক্ষে কাজটি হ'ল @Spyম্যানুয়ালি তাত্ক্ষণিক তালিকার বিরুদ্ধে একটি ব্যবহার করা এবং ম্যানুয়ালি। একক পরীক্ষার জন্য সেই তালিকায় মক অবজেক্ট (গুলি) যুক্ত করুন। সম্ভবত এটি ইচ্ছাকৃত ছিল, কারণ এটি অবশ্যই আমাকে বাধ্য হয়েছিল যা একসাথে উপহাস করা হচ্ছে তার দিকে মনোযোগ দিতে।


হ্যাঁ এটি সর্বোত্তম উপায়। স্প্রিংকিটো আসলে আমার জন্য যে কারণেই হোক না কেন সেই উপহাসকে ইনজেক্ট করে না।
chaostheory

13

হালনাগাদ: এখন এই সমস্যার আরও ভাল এবং ক্লিনার সমাধান রয়েছে। প্রথমে অন্যান্য উত্তরগুলি বিবেচনা করুন।

অবশেষে আমি তার ব্লগে ronen দ্বারা এটির উত্তর পেয়েছি। Mockito.mock(Class c)রিটার্ন ধরণের ঘোষণা করার পদ্ধতিটির কারণে আমি যে সমস্যাটি করছিলাম তা হ'ল Object। ফলস্বরূপ স্প্রিং ফ্যাক্টরি পদ্ধতি রিটার্ন টাইপ থেকে শিমের ধরণটি নির্ধারণ করতে অক্ষম।

রোনেনের সমাধানটি এমন একটি FactoryBeanবাস্তবায়ন তৈরি করা যা মককে ফিরে আসে। দ্যFactoryBeanইন্টারফেস স্প্রিং কারখানা শিম দ্বারা নির্মিত বস্তু ধরণ অনুসন্ধান করতে পারবেন।

আমার বিদ্রূপিত শিমের সংজ্ঞাটি এখন দেখে মনে হচ্ছে:

<bean id="mockDaoFactory" name="dao" class="com.package.test.MocksFactory">
    <property name="type" value="com.package.Dao" />
</bean>


আমি বুঝতে পারছি না, কারখানার পদ্ধতিতে রিটার্ন টাইপ অবজেক্ট রয়েছে ... তবে
আম্রার দ্রবণটিতে

না এই সমাধানটি, বসন্ত কারখানার শিমের প্রকারটি অনুমান করে না যে ফ্যাক্টরিবিয়ান থেকে ফিরে আসে সুতরাং কোনও ধরণের মটরশুটি [com.package.Dao] ...
লিসাক


এই লিঙ্কটি আসলে এখনও কাজ করে: জাভাদেভলমেন্টফেরমাসেস.ব্লগস্পট.com / 2008 / 07/… কেবলমাত্র আপনার ব্রাউজারে লিঙ্ক পুনর্নির্দেশটি অক্ষম করুন এবং আপনি তার নতুন ব্লগে 404 দেখার জন্য চাপ প্রয়োগ করার পরিবর্তে এটি দেখতে পাবেন।
আনুমানিক

12

স্প্রিংয়ের ৩.২ হিসাবে, এটি আর কোনও সমস্যা নয়। স্প্রিং এখন জেনেরিক কারখানার পদ্ধতির ফলাফলগুলির অটোয়্যারিং সমর্থন করে। এই ব্লগ পোস্টে "জেনেরিক ফ্যাক্টরি পদ্ধতি" শিরোনামে বিভাগটি দেখুন: http://spring.io/blog/2012/11/07/spring-framework-3-2-rc1-new-testing-features/

মূল বিষয়টি হ'ল:

বসন্ত ৩.২-এ, কারখানার পদ্ধতিগুলির জন্য জেনেরিক রিটার্নের ধরণগুলি এখন সঠিকভাবে অনুমান করা হয়েছে, এবং মকসের জন্য টাইপ করে অটোয়ারিংয়ের প্রত্যাশা অনুযায়ী কাজ করা উচিত। ফলস্বরূপ, কাস্টম ওয়ার্ক-এর চারপাশের যেমন একটি মকিতোফ্যাক্টরিবিয়ান, ইজিমোকফ্যাক্টরিবিয়ান বা স্প্রিংকিটো সম্ভবত আর প্রয়োজন নেই।

যার অর্থ এটি বাক্সের বাইরে কাজ করা উচিত:

<bean id="dao" class="org.mockito.Mockito" factory-method="mock">
    <constructor-arg value="com.package.Dao" />
</bean>

9

নীচের কোডটি অটোয়ারিংয়ের সাথে কাজ করে - এটি স্বল্পতম সংস্করণ নয় তবে কার্যকর যখন এটি কেবল স্ট্যান্ডার্ড স্প্রিং / মকিতো জারগুলির সাথে কাজ করা উচিত।

<bean id="dao" class="org.springframework.aop.framework.ProxyFactoryBean">
   <property name="target"> <bean class="org.mockito.Mockito" factory-method="mock"> <constructor-arg value="com.package.Dao" /> </bean> </property>
   <property name="proxyInterfaces"> <value>com.package.Dao</value> </property>
</bean> 

আমার জন্য কাজ করেছেন। এখানে বর্ণিত হিসাবে এটি যাচাই করার জন্য আমাকে আমার পরীক্ষায় প্রক্সিটি আন
আপ করে

9

আপনি যদি বসন্ত> = 3.0 ব্যবহার করছেন @Configurationতবে অ্যাপ্লিকেশন প্রসঙ্গে অংশটি সংজ্ঞায়িত করতে স্প্রিংস টিকা ব্যবহার করার চেষ্টা করুন

@Configuration
@ImportResource("com/blah/blurk/rest-of-config.xml")
public class DaoTestConfiguration {

    @Bean
    public ApplicationService applicationService() {
        return mock(ApplicationService.class);
    }

}

আপনি যদি @ আমদানি রিসোর্সটি ব্যবহার করতে না চান তবে এটি অন্যভাবেও করা যেতে পারে:

<beans>
    <!-- rest of your config -->

    <!-- the container recognize this as a Configuration and adds it's beans 
         to the container -->
    <bean class="com.package.DaoTestConfiguration"/>
</beans>

আরও তথ্যের জন্য, বসন্ত-ফ্রেমওয়ার্ক-রেফারেন্সটি দেখুন: জাভা ভিত্তিক ধারক কনফিগারেশন


সুন্দর. আমি যখন পরীক্ষার পরীক্ষা করছি তখন এটি ব্যবহার করা হয়েছিল আসল পরীক্ষার ক্ষেত্রে @ স্বীকৃত।
এনকোর

8

সম্ভবত নিখুঁত সমাধান নয়, তবে আমি ইউনিট পরীক্ষার জন্য ডিআই করার জন্য বসন্ত ব্যবহার করার প্রবণতা রাখি না। একক শিমের জন্য নির্ভরতা (পরীক্ষার অধীনে শ্রেণি) সাধারণত অত্যধিক জটিল হয় না তাই আমি কেবল টেস্ট কোডে সরাসরি ইনজেকশনটি করি।


3
আমি আপনার পদ্ধতি বুঝতে। তবে, আমি নিজেকে এই পরিস্থিতিতে একটি বৃহত লিগ্যাসি কোড বেসে খুঁজে পাই যা সহজেই এর জন্য মঞ্জুরি দেয় না - এখনও।
চাবিবত

1
বসন্তের দিকগুলি / এওপি (উদাহরণস্বরূপ, বসন্তের সুরক্ষা বিধি পরীক্ষা করার সময়) উপর নির্ভর করে এমন কোডের পরীক্ষা করা দরকার যখন আমি মকিতো / স্প্রিং কম্বোকে খুব দরকারী বলে খুঁজে পেয়েছি। যদিও এই দাবিগুলির ক্ষেত্রে একেবারে ন্যায়সঙ্গত যে এই জাতীয় পরীক্ষাগুলি একটি সংহতকরণ পরীক্ষা হওয়া উচিত।
লার্স ট্যাকম্যান

@ লার্স - সম্মত - আমি যে পরীক্ষাগুলিটি সম্পাদন করছি তার বিষয়ে একই কথা বলা যেতে পারে।
চাবিট

7

আমি মকিতো ব্যবহার করে নিম্নলিখিতটি করতে পারি:

<bean id="stateMachine" class="org.mockito.Mockito" factory-method="mock">
    <constructor-arg value="com.abcd.StateMachine"/>
</bean>

1
উত্তরের জন্য ধন্যবাদ আলেক্সান্ডার আমি জিজ্ঞাসা করতে পারি: এটি কি সঠিকভাবে ওয়্যার-আপ হয়? যদি তাই হয় তবে আপনি স্প্রিং / মকিতোর কোন সংস্করণ ব্যবহার করছেন?
চাবিট

6

উপরোক্ত পদ্ধতির উপর ভিত্তি করে কয়েকটি উদাহরণ পোস্ট করা

বসন্ত সহ:

@ContextConfiguration(locations = { "classpath:context.xml" })
@RunWith(SpringJUnit4ClassRunner.class)
public class TestServiceTest {
    @InjectMocks
    private TestService testService;
    @Mock
    private TestService2 testService2;
}

বসন্ত ছাড়াই:

@RunWith(MockitoJUnitRunner.class)
public class TestServiceTest {
    @InjectMocks
    private TestService testService = new TestServiceImpl();
    @Mock
    private TestService2 testService2;
}

2

আপডেট - নতুন উত্তর এখানে: https://stackoverflow.com/a/19454282/411229 । এই উত্তরটি কেবল বসন্ত সংস্করণগুলিতে 3.2 এর আগে প্রযোজ্য।

আমি এর আরও সুস্পষ্ট সমাধানের জন্য কিছুক্ষণ চেষ্টা করেছি। এই ব্লগ পোস্টটি আমার সমস্ত প্রয়োজনীয়তা আবশ্যক এবং শিমের ঘোষণার আদেশের উপর নির্ভর করে না। ম্যাটিয়াস সেভারসনকে সমস্ত কৃতিত্ব। http://www.jayway.com/2011/11/30/spring-integration-tests-part-i-creating-mock-objects/

মূলত, একটি ফ্যাক্টরিবিয়ান বাস্তবায়ন করুন

package com.jayway.springmock;

import org.mockito.Mockito;
import org.springframework.beans.factory.FactoryBean;

/**
 * A {@link FactoryBean} for creating mocked beans based on Mockito so that they 
 * can be {@link @Autowired} into Spring test configurations.
 *
 * @author Mattias Severson, Jayway
 *
 * @see FactoryBean
 * @see org.mockito.Mockito
 */
public class MockitoFactoryBean<T> implements FactoryBean<T> {

    private Class<T> classToBeMocked;

    /**
     * Creates a Mockito mock instance of the provided class.
     * @param classToBeMocked The class to be mocked.
     */
    public MockitoFactoryBean(Class<T> classToBeMocked) {
        this.classToBeMocked = classToBeMocked;
    }

    @Override
    public T getObject() throws Exception {
        return Mockito.mock(classToBeMocked);
    }

    @Override
    public Class<?> getObjectType() {
        return classToBeMocked;
    }

    @Override
    public boolean isSingleton() {
        return true;
    }
}

নিম্নলিখিতটি সহ আপনার বসন্তের কনফিগারেশনটি আপডেট করুন:

<beans...>
    <context:component-scan base-package="com.jayway.example"/>

    <bean id="someDependencyMock" class="com.jayway.springmock.MockitoFactoryBean">
        <constructor-arg name="classToBeMocked" value="com.jayway.example.SomeDependency" />
    </bean>
</beans>

2

এ খুঁজছি উন্নয়নের Springockito গতি এবং খোলা বিষয় সংখ্যা আজকাল আমার টেস্ট স্যুট স্ট্যাকটিতে এটি প্রবর্তন করতে আমি কিছুটা চিন্তিত হব। স্প্রিং 4 রিলিজের আগে সর্বশেষ প্রকাশের ঘটনাটি সত্য যে "স্প্রিং 4 এর সাথে সহজেই এটি সংহত করা সম্ভব?" এর মতো প্রশ্ন সামনে আসে। আমি জানি না, কারণ আমি চেষ্টা করেছিলাম না। ইন্টিগ্রেশন পরীক্ষায় স্প্রিং শিমের উপহাস করার প্রয়োজন হলে আমি শুদ্ধ স্প্রিং পদ্ধতির পছন্দ করি।

স্রেফ স্প্রিং স্প্রিং বৈশিষ্ট্য সহ নকল স্প্রিং বিনের বিকল্প রয়েছে। আপনি ব্যবহার করতে হবে @Primary, @Profileএবং @ActiveProfilesতার জন্য টীকা। আমি এই বিষয়ে একটি ব্লগ পোস্ট লিখেছি।


1

মক ফ্যাক্টরি তৈরি করতে তেবোটের মতো অনুরূপ উত্তর পেয়েছি যা মক সরবরাহ করে provides আমি (যেহেতু narkisr লিংক মরে) উপহাস কারখানা তৈরি করতে নিম্নলিখিত উদাহরণে ব্যবহৃত: http://hg.randompage.org/java/src/407e78aa08a0/projects/bookmarking/backend/spring/src/test/java/ সংস্থা / randompage / বুকমার্ক / ব্যাকএন্ড / testUtils / MocksFactory.java

<bean id="someFacade" class="nl.package.test.MockFactory">
    <property name="type" value="nl.package.someFacade"/>
</bean>

এটি বসন্তকে উপহাস করা শিম থেকে ইনজেকশনগুলি সমাধান করতে চায় তা প্রতিরোধ করতেও সহায়তা করে।


1
<bean id="mockDaoFactory" name="dao" class="com.package.test.MocksFactory">
    <property name="type" value="com.package.Dao" />
</bean>

এক্সএমএল ফাইলের প্রথম / প্রথম দিকে ঘোষণা করা হলে এটি পুরোপুরি ভালভাবে কাজ করে। মকিতো 1.9.0 / স্প্রিং 3.0.5


1

আমি মার্কাস টি এর উত্তরে ব্যবহৃত পদ্ধতির সংমিশ্রণটি ব্যবহার করি এবং এটির ImportBeanDefinitionRegistrarকাস্টম টীকা ( @MockedBeans) এর জন্য একটি সাধারণ সহায়ক বাস্তবায়ন দেখতে পাওয়া যায় যার মধ্যে কোনটি নির্দিষ্ট করতে পারে যে কোন শ্রেণির উপহাস করা উচিত। আমি বিশ্বাস করি যে এই পদ্ধতির ফলে বিদ্রূপ সম্পর্কিত কিছু বয়লারপ্লিট কোড মুছে ফেলা সংক্ষিপ্ত ইউনিট পরীক্ষার ফলাফল।

নমুনা ইউনিট পরীক্ষাটি সেই পদ্ধতির সাথে কীভাবে দেখায় তা এখানে:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(loader=AnnotationConfigContextLoader.class)
public class ExampleServiceIntegrationTest {

    //our service under test, with mocked dependencies injected
    @Autowired
    ExampleService exampleService;

    //we can autowire mocked beans if we need to used them in tests
    @Autowired
    DependencyBeanA dependencyBeanA;

    @Test
    public void testSomeMethod() {
        ...
        exampleService.someMethod();
        ...
        verify(dependencyBeanA, times(1)).someDependencyMethod();
    }

    /**
     * Inner class configuration object for this test. Spring will read it thanks to
     * @ContextConfiguration(loader=AnnotationConfigContextLoader.class) annotation on the test class.
     */
    @Configuration
    @Import(TestAppConfig.class) //TestAppConfig may contain some common integration testing configuration
    @MockedBeans({DependencyBeanA.class, DependencyBeanB.class, AnotherDependency.class}) //Beans to be mocked
    static class ContextConfiguration {

        @Bean
        public ExampleService exampleService() {
            return new ExampleService(); //our service under test
        }
    }
}

এটি ঘটতে আপনার দুটি সহজ সহায়ক শ্রেণি - কাস্টম টিকা ( @MockedBeans) এবং একটি কাস্টম ImportBeanDefinitionRegistrarবাস্তবায়ন সংজ্ঞা দেওয়া দরকার। @MockedBeansটীকা সংজ্ঞা সংজ্ঞায়িত করা প্রয়োজন @Import(CustomImportBeanDefinitionRegistrar.class)এবং ImportBeanDefinitionRgistrarএর registerBeanDefinitionsপদ্ধতিতে কনফিগারেশনে মশকরা বিনের সংজ্ঞা যুক্ত করা দরকার ।

আপনি যদি মতামতটি পছন্দ করেন তবে আমার ব্লগপোস্টে নমুনা প্রয়োগগুলি পেতে পারেন ।


1

আমি ক্রেসিমির নেসেকের প্রস্তাবের ভিত্তিতে একটি সমাধান তৈরি করেছি। কোডটি কিছুটা পরিচ্ছন্ন ও মডুলার করার জন্য আমি একটি নতুন টিকা @ এনেবলমকডবিয়ান যুক্ত করেছি ।

@EnableMockedBean
@SpringBootApplication
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes=MockedBeanTest.class)
public class MockedBeanTest {

    @MockedBean
    private HelloWorldService helloWorldService;

    @Autowired
    private MiddleComponent middleComponent;

    @Test
    public void helloWorldIsCalledOnlyOnce() {

        middleComponent.getHelloMessage();

        // THEN HelloWorldService is called only once
        verify(helloWorldService, times(1)).getHelloMessage();
    }

}

আমি এটি ব্যাখ্যা করে একটি পোস্ট লিখেছি ।


1

আমি আপনার প্রকল্পটি স্প্রিং বুট ১.৪ এ স্থানান্তরিত করার পরামর্শ দেব। এর পরে @MockBeanআপনি নিজের নকল করতে নতুন টিকা ব্যবহার করতে পারেনcom.package.Dao


0

আজ আমি জানতে পেরেছি যে একটি বসন্ত প্রসঙ্গে যেখানে আমি মকিতো মটরশুটিগুলির আগে একটি ঘোষনা দিয়েছি, এটি লোড করতে ব্যর্থ হয়েছিল। উপহাসগুলি পরে সরানোর পরে, অ্যাপ্লিকেশন প্রসঙ্গটি সফলভাবে লোড হয়েছিল। যত্ন নিবেন :)


1
কিছু অনুপস্থিত রয়েছে। 8-) আপনি বিদ্রূপ পরে কি সরানো হয়েছে?
হ্যান্স-পিটার স্টার

0

রেকর্ডের জন্য, আমার সমস্ত পরীক্ষাগুলি সঠিকভাবে কেবল ফিক্সচারকে অলস-সূচনাযুক্ত করে কাজ করে, যেমন:

<bean id="fixture"
      class="it.tidalwave.northernwind.rca.embeddedserver.impl.DefaultEmbeddedServer"
      lazy-init="true" /> <!-- To solve Mockito + Spring problems -->

<bean class="it.tidalwave.messagebus.aspect.spring.MessageBusAdapterFactory" />

<bean id="applicationMessageBus"
      class="org.mockito.Mockito" factory-method="mock">
    <constructor-arg value="it.tidalwave.messagebus.MessageBus" />
</bean>

<bean class="org.mockito.Mockito" factory-method="mock">
    <constructor-arg value="javax.servlet.ServletContext" />
</bean>

আমি মনে করি যৌক্তিকতা এখানে ম্যাটিয়াস ব্যাখ্যা করেছেন (পোস্টের নীচে), যে কোনও কর্মমণ্ডলটি শিমের ঘোষিত ক্রমটি পরিবর্তন করছে - অলস প্রারম্ভিকরণটি "সাজান" শেষে ফিক্সচারটি ঘোষণা করা হয়।


-1

আপনি যদি কন্ট্রোলার ইনজেকশন ব্যবহার করেন তবে নিশ্চিত হয়ে নিন যে আপনার স্থানীয় ভেরিয়েবলগুলি "চূড়ান্ত" নয়

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.