মকিতো - @ এসপি বনাম @ মোক


99

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



উত্তর:


88

প্রযুক্তিগতভাবে "মোক" এবং "গুপ্তচরবৃত্তি" উভয়ই বলা একটি বিশেষ ধরণের "টেস্ট ডাবলস"।

দুর্ভাগ্যক্রমে মকিতো পার্থক্যটি অদ্ভুত করে তুলছে।

মকিতোতে একটি মক হ'ল অন্যান্য মশকরা ফ্রেমওয়ার্কগুলিতে একটি সাধারণ উপহাস (আপনাকে অনুরোধগুলি আটকে রাখার অনুমতি দেয়; অর্থাত , পদ্ধতি কলগুলির বাইরে নির্দিষ্ট মানগুলি ফেরত দেয়)।

মকিতোতে একটি গুপ্তচর হ'ল অন্যান্য মশকরা ফ্রেমওয়ার্কগুলিতে একটি আংশিক উপহাস (বস্তুর কিছু অংশ উপহাস হবে এবং অংশটি আসল পদ্ধতি আহ্বান ব্যবহার করবে)।


41

উভয়ই পদ্ধতি বা ক্ষেত্রকে উপহাস করার জন্য ব্যবহার করা যেতে পারে। পার্থক্যটি হ'ল মক হিসাবে, আপনি গুপ্তচর থাকাকালীন একটি সম্পূর্ণ উপহাস বা জাল বস্তু তৈরি করছেন, আসল বস্তুটি রয়েছে এবং আপনি এটির নির্দিষ্ট পদ্ধতিতে গুপ্তচরবৃত্তি বা স্ট্যাবি করছেন।

স্পাই অবজেক্টে থাকা অবস্থায় অবশ্যই এটি যেহেতু একটি আসল পদ্ধতি, আপনি যখন পদ্ধতিটি স্টাবি করছেন না, তখন এটি আসল পদ্ধতির আচরণ বলে call আপনি যদি পদ্ধতিটি পরিবর্তন এবং উপহাস করতে চান তবে আপনার এটির স্টাব করা দরকার।

তুলনা হিসাবে নীচের উদাহরণ বিবেচনা করুন।

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Spy;
import org.mockito.runners.MockitoJUnitRunner;
 
import java.util.ArrayList;
import java.util.List;
 
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.when;
 
@RunWith(MockitoJUnitRunner.class)
public class MockSpy {
 
    @Mock
    private List<String> mockList;
 
    @Spy
    private List<String> spyList = new ArrayList();
 
    @Test
    public void testMockList() {
        //by default, calling the methods of mock object will do nothing
        mockList.add("test");

        Mockito.verify(mockList).add("test");
        assertEquals(0, mockList.size());
        assertNull(mockList.get(0));
    }
 
    @Test
    public void testSpyList() {
        //spy object will call the real method when not stub
        spyList.add("test");

        Mockito.verify(spyList).add("test");
        assertEquals(1, spyList.size());
        assertEquals("test", spyList.get(0));
    }
 
    @Test
    public void testMockWithStub() {
        //try stubbing a method
        String expected = "Mock 100";
        when(mockList.get(100)).thenReturn(expected);
 
        assertEquals(expected, mockList.get(100));
    }
 
    @Test
    public void testSpyWithStub() {
        //stubbing a spy method will result the same as the mock object
        String expected = "Spy 100";
        //take note of using doReturn instead of when
        doReturn(expected).when(spyList).get(100);
 
        assertEquals(expected, spyList.get(100));
    }
}

চিৎকার করলে আপনি মক বা গুপ্তচর ব্যবহার করেন? আপনি যদি নিরাপদে থাকতে চান এবং বাহ্যিক পরিষেবাগুলি কল করা এড়াতে চান এবং ইউনিটের অভ্যন্তরে কেবল যুক্তি পরীক্ষা করতে চান তবে মক ব্যবহার করুন। আপনি যদি বাহ্যিক পরিষেবাটি কল করতে এবং প্রকৃত নির্ভরতার কলিং সম্পাদন করতে চান বা বলতে পারেন, আপনি প্রোগ্রামটি যেমন চালাতে চান এবং সুনির্দিষ্ট পদ্ধতিতে স্ট্যাব করতে চান, তবে গুপ্তচর ব্যবহার করুন। সুতরাং যে মকিতো মধ্যে গুপ্তচর এবং মক মধ্যে পার্থক্য।


উত্তম উত্তর তবে এটি যাচাই (কেবল) কেবলমাত্র ত্রুটিতে ফেলবে এবং পরীক্ষাগুলি চালাবে না যতক্ষণ না আপনি আপনার তালিকা এখানে পূর্বরূপ সেটআপ () পদ্ধতিতে শুরু করেন ঠিক যেমন এখানে মকলিস্ট = মক (অ্যারেলিস্টক্লাস); স্পাইলিস্ট = গুপ্তচর (অ্যারেলিস্ট.ক্লাস); এবং এখানে প্রস্তাবিত মক এবং স্পাই টীকা মুছে ফেলুন। আমি এটি পরীক্ষা করেছি এবং আমার পরীক্ষা এখন পাস করছে।
দ্য_মার্টিয়ান

17

টিএল; ডিআর সংস্করণ,

সঙ্গে উপহাস , এটা আপনার জন্য বেয়ার-হাড় শেল উদাহরণস্বরূপ সৃষ্টি করে।

List<String> mockList = Mockito.mock(ArrayList.class);

সঙ্গে গুপ্তচর আপনি আংশিকভাবে একটি অন উপহাস করতে বিদ্যমান উদাহরণস্বরূপ

List<String> spyList = Mockito.spy(new ArrayList<String>());

স্পাইয়ের জন্য সাধারণ ব্যবহারের ক্ষেত্রে: শ্রেণিতে একটি প্যারামিটারাইজড কনস্ট্রাক্টর থাকে, আপনি প্রথমে অবজেক্টটি তৈরি করতে চান।


14

আমি এখানে একটি চলমান উদাহরণ তৈরি করেছি https://www.surasint.com/mockito-with-spy/

আমি এর কিছু এখানে অনুলিপি করছি।

আপনার কাছে এই কোডের মতো কিছু থাকলে:

public void transfer( DepositMoneyService depositMoneyService, 
                      WithdrawMoneyService withdrawMoneyService, 
                      double amount, String fromAccount, String toAccount) {
    withdrawMoneyService.withdraw(fromAccount,amount);
    depositMoneyService.deposit(toAccount,amount);
}

আপনার গোয়েন্দাগুলির প্রয়োজন নেই কারণ আপনি কেবল ডিপোজিটমনি সার্ভিস এবং উইথড্রোমনি সার্ভিসেসকে উপহাস করতে পারেন।

তবে কিছু লিগ্যাসি কোড সহ, নির্ভরতা কোডে রয়েছে:

    public void transfer(String fromAccount, String toAccount, double amount) {
        this.depositeMoneyService = new DepositMoneyService();
        this.withdrawMoneyService = new WithdrawMoneyService();
        withdrawMoneyService.withdraw(fromAccount,amount);
        depositeMoneyService.deposit(toAccount,amount);
    }

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

বিকল্পটি হ'ল আপনি নির্ভরতাটি এর বাইরে বের করতে পারেন:

    public void transfer(String fromAccount, String toAccount, double amount){
        this.depositeMoneyService = proxyDepositMoneyServiceCreator();
        this.withdrawMoneyService = proxyWithdrawMoneyServiceCreator();
        withdrawMoneyService.withdraw(fromAccount,amount);
        depositeMoneyService.deposit(toAccount,amount);
    }

    DepositMoneyService proxyDepositMoneyServiceCreator() {
        return new DepositMoneyService();
    }

    WithdrawMoneyService proxyWithdrawMoneyServiceCreator() {
        return new WithdrawMoneyService();
    }

তারপরে আপনি গুপ্তচরকে ইনজেকশনটি এর মতো নির্ভরতা ব্যবহার করতে পারেন:

DepositMoneyService mockDepositMoneyService = mock(DepositMoneyService.class);
        WithdrawMoneyService mockWithdrawMoneyService = mock(WithdrawMoneyService.class);

    TransferMoneyService target = spy(new TransferMoneyService());

    doReturn(mockDepositMoneyService)
            .when(target)
            .proxyDepositMoneyServiceCreator();

    doReturn(mockWithdrawMoneyService)
            .when(target)
            .proxyWithdrawMoneyServiceCreator();

উপরের লিঙ্কে আরও বিশদ।


13

শুরু করার সর্বোত্তম জায়গাটি সম্ভবত মকিতোর জন্য ডক্স

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

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

আপনি যে যুক্তিকে পরীক্ষা করছেন তা যদি ডাটাবেস সংযোগের বিষয়ে চিন্তা না করে তবে আপনি সেই পদ্ধতিটি স্টাবের সাথে প্রতিস্থাপন করতে পারেন যা একটি হার্ড কোডিং মান দেয়।

মকিতো গুপ্তচর আপনাকে কোনও পদ্ধতি অন্য পদ্ধতিতে কল দেয় কিনা তা পরীক্ষা করতে দেয়। পরীক্ষার অধীনে লিগ্যাসি কোড পাওয়ার চেষ্টা করার সময় এটি খুব কার্যকর হতে পারে।

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


7

সংক্ষেপে:

@Spyএবং @Mockকোডের পরীক্ষায় খুব বেশি ব্যবহৃত হয়, তবে বিকাশকারীরা তাদের মধ্যে কোনওটি ব্যবহার করার ক্ষেত্রে বিভ্রান্ত হন এবং এভাবে বিকাশকারীরা @Mockনিরাপদ থাকতে ব্যবহার করতে শেষ করেন ।

  • @Mockযখন আপনি কেবল সেই পদ্ধতিটি কল না করে কেবলমাত্র বাহ্যিকভাবে কার্যকারিতা পরীক্ষা করতে চান তখন ব্যবহার করুন ।
  • @Spyআপনি যখন বহিরাগতভাবে কার্যকারিতা পরীক্ষা করতে চান তখন ব্যবহার করুন + খুব অভ্যন্তরীণ পদ্ধতিতে ডাকা হচ্ছে।

নীচে আমি আমেরিকাতে ইলেকশন ২০ এক্সএক্সএক্সএক্সের দৃশ্যধারণ করেছি তার উদাহরণ নীচে দেওয়া হল ।

ভোটারদের অনুযায়ী VotersOfBelow21এবং অনুসারে ভাগ করা যায় VotersOfABove21

আদর্শ এক্সিট পোল বলছে যে ট্রাম্প নির্বাচনে জয়লাভ করবেন কারণ VotersOfBelow21এবং VotersOfABove21দুজনেই ট্রাম্পকে " আমরা রাষ্ট্রপতি ট্রাম্প নির্বাচিত করেছি " বলে ভোট দেবেন।

তবে এটি আসল দৃশ্য নয়:

উভয় বয়সের ভোটাররা ট্রাম্পকে ভোট দিয়েছিলেন কারণ মিঃ ট্রাম্প ব্যতীত তাদের আর কোনও কার্যকর পছন্দ ছিল না।

তাহলে আপনি এটি কিভাবে পরীক্ষা করবেন ??

public class VotersOfAbove21 {
public void weElected(String myVote){
  System.out.println("Voters of above 21 has no Choice Than Thrump in 20XX ");
}
}

public class VotersOfBelow21 {
  public void weElected(String myVote){
    System.out.println("Voters of below 21 has no Choice Than Thrump in 20XX");
  }
}

public class ElectionOfYear20XX {
  VotersOfAbove21 votersOfAbove21;
  VotersOfBelow21 votersOfBelow21;
  public boolean weElected(String WeElectedTrump){
    votersOfAbove21.weElected(WeElectedTrump);
    System.out.println("We elected President Trump ");

    votersOfBelow21.weElected(WeElectedTrump);
    System.out.println("We elected President Trump ");
    return true;
  }

}

এখন উপরের প্রথম দুটি শ্রেণিতে নোট করুন, উভয় বয়সের লোকেরা বলেছেন যে তাদের ট্রাম্পের চেয়ে ভাল পছন্দ নেই। যার স্পষ্টরূপে অর্থ হ'ল তারা ট্রাম্পের পক্ষে ভোট দিয়েছেন কেবল কারণ তাদের কোনও বিকল্প ছিল না।

এখন ElectionOfYear20XX জনগণ বলেছে যে ট্রাম্প জিতেছেন কারণ উভয় বয়সেরাই তাকে বিপুল ভোটে ভোট দিয়েছিল ed

যদি আমরা ElectionOfYear20XX@ মক দিয়ে পরীক্ষার জন্য যাই, তবে ট্রাম্প কেন জিতলেন তার আসল কারণ আমরা পেতে পারি না, আমরা কেবল বাহ্যিক কারণ পরীক্ষা করব।

যদি আমরা ElectionOfYear20XX@ এসপিএস দিয়ে পরীক্ষা করে দেখি, তবে ট্রাম্প বাহ্যিক প্রস্থান পোলের ফলাফলগুলি, অর্থাৎ অভ্যন্তরীণভাবে + বাহ্যিকভাবে কেন জিতলেন তার আসল কারণটি আমরা পেয়েছি।


আমাদের ELectionOfYear20XX_Testক্লাস:

@RunWith(MockitoJUnitRunner.class)
public class ELectionOfYear20XX_Test {

  @Mock
  VotersOfBelow21 votersOfBelow21;
  @Mock
  VotersOfAbove21 votersOfAbove21;
  @InjectMocks
  ElectionOfYear20XX electionOfYear20XX;
  @Test
  public void testElectionResults(){
    Assert.assertEquals(true,electionOfYear20XX.weElected("No Choice"));
  }

}

এটি কেবল যুক্তি পরীক্ষার ফলাফলগুলি যেমন বাহ্যিক চেক আউটপুট করা উচিত :

We elected President Trump 
We elected President Trump 

নিয়ে পরীক্ষা @Spyপ্রকৃত পদ্ধতি আবাহন সঙ্গে বাইরে সেইসাথে অভ্যন্তরীণভাবে।

@RunWith(MockitoJUnitRunner.class)
public class ELectionOfYear20XX_Test {

  @Spy
  VotersOfBelow21 votersOfBelow21;
  @Spy
  VotersOfAbove21 votersOfAbove21;
  @InjectMocks
  ElectionOfYear20XX electionOfYear20XX;
  @Test
  public void testElectionResults(){
    Assert.assertEquals(true,electionOfYear20XX.weElected("No Choice"));
  }

}

আউটপুট:

Voters of above 21 has no Choice Than Thrump in 20XX 
We elected President Trump 
Voters of below 21 has no Choice Than Thrump in 20XX
We elected President Trump 

6

আমি এই সুপারিশের সরলতা পছন্দ করি:

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

সূত্র: https://javapointers.com/tutorial/differences-between-spy-and-mock-in-mockito/

একটি সাধারণ পার্থক্য হ'ল:

  • আপনি যদি কোনও নির্ভরতার পদ্ধতি (গুলি) সরাসরি আটকাতে চান তবে সেই নির্ভরতাটি মক করুন
  • আপনি যদি কোনও নির্ভরতার মধ্যে ডেটা স্টাব করতে চান যাতে এর সমস্ত পদ্ধতিগুলি আপনার প্রয়োজনীয় পরীক্ষার মানগুলি ফিরিয়ে দেয়, তবে সেই নির্ভরতা স্পাই করুন

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