স্পক পরীক্ষার কাঠামোর ক্ষেত্রে মক / স্টাব / স্পাইয়ের মধ্যে পার্থক্য


103

আমি স্পক পরীক্ষায় মোক, স্টাব, এবং স্পাইয়ের মধ্যে পার্থক্য বুঝতে পারি না এবং আমি অনলাইনে যে টিউটোরিয়ালগুলি দেখছি সেগুলি তাদের বিশদভাবে ব্যাখ্যা করবেন না।

উত্তর:


97

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

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

স্টাব হ'ল একটি ডামি ক্লাস যা আরও কিছু নির্দিষ্ট, প্রস্তুত বা প্রাক-রেকর্ডকৃত, পরীক্ষার অধীনে নির্দিষ্ট অনুরোধগুলিতে পুনরায় খেলানো ফলাফল সরবরাহ করে। আপনি বলতে পারেন যে স্টাবটি অভিনব মক। স্পকে আপনি প্রায়শই স্টাবের পদ্ধতি সম্পর্কে পড়বেন।

একটি গুপ্তচর হ'ল রিয়েল অবজেক্ট এবং স্টাবের মধ্যে একটি হাইব্রিড জাতীয় অর্থাত্ স্টাবের পদ্ধতি দ্বারা ছায়াযুক্ত কয়েকটি (সমস্ত নয়) পদ্ধতি সহ এটি মূলত আসল বস্তু। স্ট্যাবডবিহীন পদ্ধতিগুলি কেবলমাত্র আসল অবজেক্টে পৌঁছে যায়। এইভাবে আপনার "সস্তা" বা তুচ্ছ পদ্ধতিতে এবং "ব্যয়বহুল" বা জটিল পদ্ধতির জন্য জাল আচরণ থাকতে পারে behavior


আপডেট 2017-02-06: প্রকৃতপক্ষে ব্যবহারকারী মিখাইলের উত্তরটি আমার উপরের মূলটির তুলনায় স্পকের সাথে আরও নির্দিষ্ট। সুতরাং স্পকের সুযোগের মধ্যে তিনি যা বর্ণনা করেছেন তা সঠিক তবে এটি আমার সাধারণ উত্তরটিকে মিথ্যাবাদী করে না:

  • একটি স্টাব নির্দিষ্ট আচরণের অনুকরণের সাথে সম্পর্কিত। স্পকের মধ্যে এটি সমস্ত স্টাবই করতে পারে, তাই এটি সহজতম জিনিস।
  • একটি উপহাসটি (সম্ভবত ব্যয়বহুল) সত্যিকারের অবজেক্টটির জন্য দাঁড়িয়ে সমস্ত পদ্ধতির কলের জন্য কোনও উত্তর নেই no এক্ষেত্রে, একটি ঠোঁটের চেয়ে একটি উপহাস সহজ। তবে স্পকে, একটি মক পদ্ধতি পদ্ধতির ফলাফলগুলিও স্তম্ভিত করতে পারে, অর্থাত্ মোক এবং স্টাব উভয়ই হতে পারে। তদ্ব্যতীত, স্পকে আমরা একটি পরীক্ষার সময় নির্দিষ্ট পরামিতিগুলির সাথে নির্দিষ্ট মক পদ্ধতিগুলি কতবার ডাকা হত তা গণনা করতে পারি।
  • কোনও গুপ্তচর সর্বদা একটি আসল অবজেক্টকে আবৃত করে এবং ডিফল্ট রুটের মাধ্যমে সমস্ত পদ্ধতি আসল অবজেক্টে কল করে, মূল ফলাফলগুলির মধ্য দিয়েও যায়। পদ্ধতি কল গণনাও গুপ্তচরদের জন্য কাজ করে। স্পকে, কোনও গুপ্তচরও মূল কলটির পরামিতিগুলি এবং / অথবা ফলাফলগুলিতে হেরফের করে বা আসল পদ্ধতিগুলিকে একেবারে ডাকা থেকে আটকাতে, আসল অবজেক্টের আচরণ পরিবর্তন করতে পারে।

এখন এখানে একটি সম্পাদনযোগ্য উদাহরণ পরীক্ষা রয়েছে যা প্রদর্শিত এবং কী সম্ভব নয় তা প্রদর্শন করে। এটি মিখাইলের স্নিপেটগুলির চেয়ে কিছুটা শিক্ষণীয়। আমার নিজের উত্তরকে উন্নত করতে অনুপ্রাণিত করার জন্য তাকে অনেক ধন্যবাদ! :-)

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?")
  }
}

মোক এবং স্টাবের মধ্যে পার্থক্য এখানে পরিষ্কার নয়। বিদ্রূপের সাথে, কেউ আচরণটি যাচাই করতে চায় (যদি এবং পদ্ধতিটি কতবার বলা হচ্ছে)। স্টাবগুলি সহ, কেউ কেবলমাত্র রাষ্ট্রটি যাচাই করে (উদাহরণস্বরূপ পরীক্ষার পরে সংগ্রহের আকার)। এফওয়াইআই: মকগুলি প্রস্তুত ফলাফলও সরবরাহ করতে পারে।
চিপিক

আপনার মতামতের জন্য @ মিখাইল এবং চিপিক ধন্যবাদ Thanks আমি আমার উত্তর আপডেট করেছি, আশা করি আমি লেখার কয়েকটি বিষয় উন্নত ও স্পষ্ট করে বলছি। দাবি অস্বীকার: আমার মূল উত্তরে আমি বলেছিলাম যে আমি স্পোক-সম্পর্কিত কিছু তথ্যকে তুলনামূলকভাবে তুলনায় এবং কিছুটা মিথ্যা বলছিলাম। আমি চেয়েছিলাম লোকেরা স্টাব্বিং, বিদ্রূপ ও গুপ্তচরবৃত্তির মূল পার্থক্যগুলি বুঝতে পারে।
kriegaex

@ চিপিক, আপনার মন্তব্যের জবাব হিসাবে আরও একটি বিষয়: আমি বহু বছর ধরে উন্নয়ন দলকে কোচিং করে আসছি এবং তাদেরকে অন্যান্য মক ফ্রেমওয়ার্ক সহ স্পোক বা অন্যান্য ইউএনইটি ব্যবহার করতে দেখছি। বেশিরভাগ ক্ষেত্রে বিদ্রূপ ব্যবহার করার সময়, তারা আচরণটি যাচাইকরণের জন্য (যেমন গণনা পদ্ধতি কলগুলি) না করে পরীক্ষার অধীনে বিষয়টিকে তার পরিবেশ থেকে পৃথক করার জন্য এটি করেনি। ইন্টারঅ্যাকশন গণনা আইএমও হ'ল একটি অ্যাড অন গুডি এবং চিন্তাভাবনা করে এবং স্বচ্ছভাবে ব্যবহার করা উচিত কারণ যখন তারা আসল আচরণের চেয়ে আরও বেশি উপাদানগুলির তারের পরীক্ষা করে তখন এই জাতীয় পরীক্ষাগুলি ভাঙার প্রবণতা থাকে।
kriegaex

এটির সংক্ষিপ্ত তবে এখনও খুব সহায়ক উত্তর
ডেডপুল

54

প্রশ্নটি স্পক কাঠামোর প্রসঙ্গে ছিল এবং আমি বিশ্বাস করি না যে বর্তমানের উত্তরগুলি এটিকে বিবেচনায় রাখে।

স্পক ডক্সের ভিত্তিতে (উদাহরণগুলি কাস্টমাইজ করা হয়েছে, আমার নিজস্ব শব্দ যুক্ত হয়েছে):

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

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
}

সারসংক্ষেপ:

  • একটি স্টাব () একটি স্টাব।
  • একটি মক () একটি স্টাব এবং মক।
  • একটি স্পাই () একটি স্টাব, মক এবং স্পাই।

স্টাব () পর্যাপ্ত হলে মক () ব্যবহার এড়িয়ে চলুন।

আপনি যদি পারেন তবে স্পাই () ব্যবহার করা এড়িয়ে চলুন, এটি করা গন্ধ এবং পরীক্ষার অধীনে ভুল পরীক্ষায় বা অবজেক্টের ভুল নকশার ইঙ্গিত হতে পারে।


4
কেবল যোগ করার জন্য: আপনি মোকগুলির ব্যবহারকে হ্রাস করতে চান এমন আরও একটি কারণ হ'ল একটি মোক একটি দৃsert়তার সাথে অনুরূপ, যাতে আপনি পরীক্ষায় ব্যর্থ হতে পারে এমন একটি মোকের উপর এমন জিনিসগুলি পরীক্ষা করেন এবং আপনি সর্বদা পরীক্ষার পরিমাণ হ্রাস করতে চান আপনি পরীক্ষা কেন্দ্রীভূত এবং সহজ রাখতে পরীক্ষা। সুতরাং আদর্শগতভাবে প্রতি পরীক্ষায় কেবল একটি মক করা উচিত।
সম্মি

4
"এ স্পাই () হ'ল স্টাব, মক এবং স্পাই।" সিনান গুপ্তচরদের জন্য এটি সত্য নয়?
বেসিকরেল

4
আমি সাইনোন গুপ্তচরদের এক ঝলক দেখেছি এবং তারা দেখে মনে হচ্ছে তারা মক বা স্টাবের মতো আচরণ করে না। মনে রাখবেন যে এই প্রশ্ন / উত্তরটি স্পোকের প্রসঙ্গে, যা জেএস নয়, গ্রোভী is
মিখাইল

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

13

সহজ অর্থে:

উপহাস: আপনি কোনও প্রকারের উপহাস করেন এবং উড়তে গিয়ে আপনি কোনও বস্তু তৈরি করেন। এই মক অবজেক্টের পদ্ধতিগুলি প্রত্যাবর্তনের প্রকারের ডিফল্ট মানগুলি দেয়।

স্টাব: আপনি একটি স্টাব ক্লাস তৈরি করেন যেখানে আপনার প্রয়োজন অনুযায়ী পদ্ধতিগুলি সংজ্ঞা দিয়ে পুনরায় সংজ্ঞায়িত করা হয়। উদাহরণস্বরূপ: আসল অবজেক্ট পদ্ধতিতে আপনি কল এবং বাহ্যিক এপিআই এবং ব্যবহারকারীর নাম এবং আইডি ফিরিয়ে আনবেন। স্ট্যাবড অবজেক্ট পদ্ধতিতে আপনি কিছু ডামি নাম ফিরিয়ে দেন।

স্পাই: আপনি একটি বাস্তব বস্তু তৈরি করেন এবং তারপরে আপনি এটি গুপ্তচর। এখন আপনি কিছু পদ্ধতি উপহাস করতে পারেন এবং কিছুটির জন্য এটি না করা বেছে নিয়েছেন।

একটি ব্যবহারের পার্থক্য হ'ল আপনি পদ্ধতি স্তরের বিষয়গুলিকে উপহাস করতে পারবেন না। যদিও আপনি পদ্ধতিতে একটি ডিফল্ট অবজেক্ট তৈরি করতে পারেন এবং তারপরে গুপ্তচর বস্তুতে পদ্ধতিগুলির পছন্দসই আচরণ পেতে এটিতে গুপ্তচরবৃত্তি করতে পারেন।


0

স্টাবগুলি কেবলমাত্র ইউনিট পরীক্ষার সুবিধার্থে, তারা পরীক্ষার অংশ নয়। মকস, পরীক্ষার অংশ, যাচাইয়ের অংশ, পাসের অংশ / ব্যর্থ।

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

আপনি যদি কোনও কিছু পরিবর্তন করেন, বা অবজেক্টের সাথে কোনও প্রকারের ইন্টারঅ্যাকশন যাচাই করতে চান তবে এটি একটি বিদ্রূপ।

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