আমি স্পক পরীক্ষায় মোক, স্টাব, এবং স্পাইয়ের মধ্যে পার্থক্য বুঝতে পারি না এবং আমি অনলাইনে যে টিউটোরিয়ালগুলি দেখছি সেগুলি তাদের বিশদভাবে ব্যাখ্যা করবেন না।
আমি স্পক পরীক্ষায় মোক, স্টাব, এবং স্পাইয়ের মধ্যে পার্থক্য বুঝতে পারি না এবং আমি অনলাইনে যে টিউটোরিয়ালগুলি দেখছি সেগুলি তাদের বিশদভাবে ব্যাখ্যা করবেন না।
উত্তর:
মনোযোগ: আমি ওভারসিম্প্লিফাই করতে যাচ্ছি এবং সম্ভবত সামনের অনুচ্ছেদে কিছুটা মিথ্যাও বলব। আরও বিস্তারিত তথ্যের জন্য মার্টিন ফওলারের ওয়েবসাইট দেখুন ।
মক হ'ল একটি ডামি ক্লাস যা সত্যিকারের প্রতিস্থাপন করে, প্রতিটি পদ্ধতি কলের জন্য নাল বা 0 এর মতো কিছু ফিরিয়ে দেয়। আপনার যদি এমন জটিল শ্রেণীর একটি ছদ্মবেশী দৃষ্টান্ত প্রয়োজন হয় যা অন্যথায় নেটওয়ার্ক সংযোগ, ফাইল বা ডাটাবেস বা সম্ভবত কয়েক ডজন অন্যান্য বস্তু ব্যবহার করে তবে বাহ্যিক সংস্থান ব্যবহার করে You উপহাসের সুবিধা হ'ল আপনি পরীক্ষার অধীনে ক্লাসটি বাকী সিস্টেম থেকে আলাদা করতে পারবেন।
স্টাব হ'ল একটি ডামি ক্লাস যা আরও কিছু নির্দিষ্ট, প্রস্তুত বা প্রাক-রেকর্ডকৃত, পরীক্ষার অধীনে নির্দিষ্ট অনুরোধগুলিতে পুনরায় খেলানো ফলাফল সরবরাহ করে। আপনি বলতে পারেন যে স্টাবটি অভিনব মক। স্পকে আপনি প্রায়শই স্টাবের পদ্ধতি সম্পর্কে পড়বেন।
একটি গুপ্তচর হ'ল রিয়েল অবজেক্ট এবং স্টাবের মধ্যে একটি হাইব্রিড জাতীয় অর্থাত্ স্টাবের পদ্ধতি দ্বারা ছায়াযুক্ত কয়েকটি (সমস্ত নয়) পদ্ধতি সহ এটি মূলত আসল বস্তু। স্ট্যাবডবিহীন পদ্ধতিগুলি কেবলমাত্র আসল অবজেক্টে পৌঁছে যায়। এইভাবে আপনার "সস্তা" বা তুচ্ছ পদ্ধতিতে এবং "ব্যয়বহুল" বা জটিল পদ্ধতির জন্য জাল আচরণ থাকতে পারে behavior
আপডেট 2017-02-06: প্রকৃতপক্ষে ব্যবহারকারী মিখাইলের উত্তরটি আমার উপরের মূলটির তুলনায় স্পকের সাথে আরও নির্দিষ্ট। সুতরাং স্পকের সুযোগের মধ্যে তিনি যা বর্ণনা করেছেন তা সঠিক তবে এটি আমার সাধারণ উত্তরটিকে মিথ্যাবাদী করে না:
এখন এখানে একটি সম্পাদনযোগ্য উদাহরণ পরীক্ষা রয়েছে যা প্রদর্শিত এবং কী সম্ভব নয় তা প্রদর্শন করে। এটি মিখাইলের স্নিপেটগুলির চেয়ে কিছুটা শিক্ষণীয়। আমার নিজের উত্তরকে উন্নত করতে অনুপ্রাণিত করার জন্য তাকে অনেক ধন্যবাদ! :-)
package de.scrum_master.stackoverflow
import org.spockframework.mock.TooFewInvocationsError
import org.spockframework.runtime.InvalidSpecException
import spock.lang.FailsWith
import spock.lang.Specification
class MockStubSpyTest extends Specification {
static class Publisher {
List<Subscriber> subscribers = new ArrayList<>()
void addSubscriber(Subscriber subscriber) {
subscribers.add(subscriber)
}
void send(String message) {
for (Subscriber subscriber : subscribers)
subscriber.receive(message);
}
}
static interface Subscriber {
String receive(String message)
}
static class MySubscriber implements Subscriber {
@Override
String receive(String message) {
if (message ==~ /[A-Za-z ]+/)
return "ok"
return "uh-oh"
}
}
Subscriber realSubscriber1 = new MySubscriber()
Subscriber realSubscriber2 = new MySubscriber()
Publisher publisher = new Publisher(subscribers: [realSubscriber1, realSubscriber2])
def "Real objects can be tested normally"() {
expect:
realSubscriber1.receive("Hello subscribers") == "ok"
realSubscriber1.receive("Anyone there?") == "uh-oh"
}
@FailsWith(TooFewInvocationsError)
def "Real objects cannot have interactions"() {
when:
publisher.send("Hello subscribers")
publisher.send("Anyone there?")
then:
2 * realSubscriber1.receive(_)
}
def "Stubs can simulate behaviour"() {
given:
def stubSubscriber = Stub(Subscriber) {
receive(_) >>> ["hey", "ho"]
}
expect:
stubSubscriber.receive("Hello subscribers") == "hey"
stubSubscriber.receive("Anyone there?") == "ho"
stubSubscriber.receive("What else?") == "ho"
}
@FailsWith(InvalidSpecException)
def "Stubs cannot have interactions"() {
given: "stubbed subscriber registered with publisher"
def stubSubscriber = Stub(Subscriber) {
receive(_) >> "hey"
}
publisher.addSubscriber(stubSubscriber)
when:
publisher.send("Hello subscribers")
publisher.send("Anyone there?")
then:
2 * stubSubscriber.receive(_)
}
def "Mocks can simulate behaviour and have interactions"() {
given:
def mockSubscriber = Mock(Subscriber) {
3 * receive(_) >>> ["hey", "ho"]
}
publisher.addSubscriber(mockSubscriber)
when:
publisher.send("Hello subscribers")
publisher.send("Anyone there?")
then: "check interactions"
1 * mockSubscriber.receive("Hello subscribers")
1 * mockSubscriber.receive("Anyone there?")
and: "check behaviour exactly 3 times"
mockSubscriber.receive("foo") == "hey"
mockSubscriber.receive("bar") == "ho"
mockSubscriber.receive("zot") == "ho"
}
def "Spies can have interactions"() {
given:
def spySubscriber = Spy(MySubscriber)
publisher.addSubscriber(spySubscriber)
when:
publisher.send("Hello subscribers")
publisher.send("Anyone there?")
then: "check interactions"
1 * spySubscriber.receive("Hello subscribers")
1 * spySubscriber.receive("Anyone there?")
and: "check behaviour for real object (a spy is not a mock!)"
spySubscriber.receive("Hello subscribers") == "ok"
spySubscriber.receive("Anyone there?") == "uh-oh"
}
def "Spies can modify behaviour and have interactions"() {
given:
def spyPublisher = Spy(Publisher) {
send(_) >> { String message -> callRealMethodWithArgs("#" + message) }
}
def mockSubscriber = Mock(MySubscriber)
spyPublisher.addSubscriber(mockSubscriber)
when:
spyPublisher.send("Hello subscribers")
spyPublisher.send("Anyone there?")
then: "check interactions"
1 * mockSubscriber.receive("#Hello subscribers")
1 * mockSubscriber.receive("#Anyone there?")
}
}
প্রশ্নটি স্পক কাঠামোর প্রসঙ্গে ছিল এবং আমি বিশ্বাস করি না যে বর্তমানের উত্তরগুলি এটিকে বিবেচনায় রাখে।
স্পক ডক্সের ভিত্তিতে (উদাহরণগুলি কাস্টমাইজ করা হয়েছে, আমার নিজস্ব শব্দ যুক্ত হয়েছে):
স্টাব: সহযোগীদের একটি নির্দিষ্ট উপায়ে পদ্ধতি কলগুলিতে সাড়া দেওয়ার জন্য ব্যবহৃত হয়। কোনও পদ্ধতিতে স্ট্যাবিং করার সময়, আপনি কীভাবে এবং কতবার পদ্ধতিটি কল করতে চলেছেন তা বিবেচনা করবেন না; আপনি কেবল এটির কিছু মূল্য ফেরত দিতে চান বা যখনই এটি কল হয়ে যায় তখন কোনও পার্শ্ব প্রতিক্রিয়া সম্পাদন করুন।
subscriber.receive(_) >> "ok" // subscriber is a Stub()
মোক: নির্দিষ্টকরণের অধীনে অবজেক্ট এবং এর সহযোগীদের মধ্যে মিথস্ক্রিয়া বর্ণনা করতে ব্যবহৃত হয়।
def "should send message to subscriber"() {
when:
publisher.send("hello")
then:
1 * subscriber.receive("hello") // subscriber is a Mock()
}
একটি মোক একটি মোক এবং একটি স্টাব হিসাবে কাজ করতে পারে:
1 * subscriber.receive("message1") >> "ok" // subscriber is a Mock()
স্পাই: সবসময় আসল জিনিসগুলির সাথে আসল জিনিসগুলির উপর ভিত্তি করে আসল জিনিসগুলি করে। নির্বাচিত পদ্ধতির রিটার্ন মান পরিবর্তন করতে স্টাবের মতো ব্যবহার করা যেতে পারে। মিথস্ক্রিয়া বর্ণনা করার জন্য একটি মোক হিসাবে ব্যবহার করা যেতে পারে।
def subscriber = Spy(SubscriberImpl, constructorArgs: ["Fred"])
def "should send message to subscriber"() {
when:
publisher.send("hello")
then:
1 * subscriber.receive("message1") >> "ok" // subscriber is a Spy(), used as a Mock an Stub
}
def "should send message to subscriber (actually handle 'receive')"() {
when:
publisher.send("hello")
then:
1 * subscriber.receive("message1") // subscriber is a Spy(), used as a Mock, uses real 'receive' function
}
সারসংক্ষেপ:
স্টাব () পর্যাপ্ত হলে মক () ব্যবহার এড়িয়ে চলুন।
আপনি যদি পারেন তবে স্পাই () ব্যবহার করা এড়িয়ে চলুন, এটি করা গন্ধ এবং পরীক্ষার অধীনে ভুল পরীক্ষায় বা অবজেক্টের ভুল নকশার ইঙ্গিত হতে পারে।
সহজ অর্থে:
উপহাস: আপনি কোনও প্রকারের উপহাস করেন এবং উড়তে গিয়ে আপনি কোনও বস্তু তৈরি করেন। এই মক অবজেক্টের পদ্ধতিগুলি প্রত্যাবর্তনের প্রকারের ডিফল্ট মানগুলি দেয়।
স্টাব: আপনি একটি স্টাব ক্লাস তৈরি করেন যেখানে আপনার প্রয়োজন অনুযায়ী পদ্ধতিগুলি সংজ্ঞা দিয়ে পুনরায় সংজ্ঞায়িত করা হয়। উদাহরণস্বরূপ: আসল অবজেক্ট পদ্ধতিতে আপনি কল এবং বাহ্যিক এপিআই এবং ব্যবহারকারীর নাম এবং আইডি ফিরিয়ে আনবেন। স্ট্যাবড অবজেক্ট পদ্ধতিতে আপনি কিছু ডামি নাম ফিরিয়ে দেন।
স্পাই: আপনি একটি বাস্তব বস্তু তৈরি করেন এবং তারপরে আপনি এটি গুপ্তচর। এখন আপনি কিছু পদ্ধতি উপহাস করতে পারেন এবং কিছুটির জন্য এটি না করা বেছে নিয়েছেন।
একটি ব্যবহারের পার্থক্য হ'ল আপনি পদ্ধতি স্তরের বিষয়গুলিকে উপহাস করতে পারবেন না। যদিও আপনি পদ্ধতিতে একটি ডিফল্ট অবজেক্ট তৈরি করতে পারেন এবং তারপরে গুপ্তচর বস্তুতে পদ্ধতিগুলির পছন্দসই আচরণ পেতে এটিতে গুপ্তচরবৃত্তি করতে পারেন।
স্টাবগুলি কেবলমাত্র ইউনিট পরীক্ষার সুবিধার্থে, তারা পরীক্ষার অংশ নয়। মকস, পরীক্ষার অংশ, যাচাইয়ের অংশ, পাসের অংশ / ব্যর্থ।
সুতরাং, বলুন আপনার কাছে এমন একটি পদ্ধতি রয়েছে যা কোনও অবজেক্টকে প্যারামিটার হিসাবে গ্রহণ করে। পরীক্ষায় এই প্যারামিটারটি পরিবর্তন করে এমন কোনও কিছুই আপনি কখনও করেন না। আপনি কেবল এটি থেকে একটি মান পড়ুন। এটা একগুঁয়ে
আপনি যদি কোনও কিছু পরিবর্তন করেন, বা অবজেক্টের সাথে কোনও প্রকারের ইন্টারঅ্যাকশন যাচাই করতে চান তবে এটি একটি বিদ্রূপ।