@ মোক এবং @ ইনজেক্টমোকসের মধ্যে পার্থক্য


উত্তর:


541

@Mockএকটি উপহাস তৈরি করে। @InjectMocksক্লাসের একটি উদাহরণ তৈরি করে এবং @Mock(বা @Spy) টীকাগুলি দিয়ে তৈরি করা শোকগুলি এই সংক্ষেপে ইনজেক্ট করে ।

নোট করুন যে আপনাকে অবশ্যই এই মকগুলি ব্যবহার করতে @RunWith(MockitoJUnitRunner.class)বা Mockito.initMocks(this)আরম্ভ করতে এবং সেগুলি ইনজেক্ট করতে হবে।

@RunWith(MockitoJUnitRunner.class)
public class SomeManagerTest {

    @InjectMocks
    private SomeManager someManager;

    @Mock
    private SomeDependency someDependency; // this will be injected into someManager

     //tests...

}

2
সংক্ষিপ্ত এবং সংক্ষিপ্ত উত্তর।
সহায়কও

এটি কি ট্রানজিটিভ নির্ভরতা বা কেবল প্রত্যক্ষ সদস্যদের জন্য কাজ করে?
পিয়েরে থিবল্ট

@ পিয়ারটিহিবল্ট ইনজেকশন বিদ্রূপগুলি কেবল প্রত্যক্ষ সদস্যদের জন্যই কাজ করে তবে আপনি গভীর মজাদারদের স্ট্যাটিক.জ্যাভডোক.ইও
টম ভেরেলস্ট

1
আমি মনে এই অনলাইন প্রবন্ধের সবচেয়ে তুলনায় অনেক স্পষ্ট .... যে আমার গাধা সংরক্ষণ সামান্য মন্তব্য ...
IHC_Applroid

আমার কাছে এমন কিছু আইটেম রয়েছে যা প্রসঙ্গের মতো @ মক টিকা দ্বারা সরবরাহ করা যায় না। আমি কীভাবে এটি প্রধান শ্রেণীর জন্য সরবরাহ করতে পারি?
মাহদি

220

এই কীভাবে একটি নমুনা কোড @Mockএবং @InjectMocksকাজ করে।

বলুন আমাদের আছে Gameএবং Playerক্লাস।

class Game {

    private Player player;

    public Game(Player player) {
        this.player = player;
    }

    public String attack() {
        return "Player attack with: " + player.getWeapon();
    }

}

class Player {

    private String weapon;

    public Player(String weapon) {
        this.weapon = weapon;
    }

    String getWeapon() {
        return weapon;
    }
}

আপনি দেখতে হিসাবে, Gameবর্গ Playerএকটি সঞ্চালন করা প্রয়োজন attack

@RunWith(MockitoJUnitRunner.class)
class GameTest {

    @Mock
    Player player;

    @InjectMocks
    Game game;

    @Test
    public void attackWithSwordTest() throws Exception {
        Mockito.when(player.getWeapon()).thenReturn("Sword");

        assertEquals("Player attack with: Sword", game.attack());
    }

}

মকিতো কোনও প্লেয়ার শ্রেণিকে উপহাস করবে এবং এটি ব্যবহার whenএবং thenReturnপদ্ধতি ব্যবহার করে । শেষ @InjectMocksঅবধি , মকিতো ব্যবহার করে এটি এতে Playerপ্রবেশ করবে Game

লক্ষ্য করুন যে আপনাকে এমনকি কোনও new Gameবস্তু তৈরি করতে হবে না । মকিতো এটি আপনার জন্য ইনজেক্ট করবে।

// you don't have to do this
Game game = new Game(player);

@Spyটীকাগুলি ব্যবহার করে আমরাও একই আচরণ পাব । এমনকি বৈশিষ্ট্যের নামটি আলাদা হলেও।

@RunWith(MockitoJUnitRunner.class)
public class GameTest {

  @Mock Player player;

  @Spy List<String> enemies = new ArrayList<>();

  @InjectMocks Game game;

  @Test public void attackWithSwordTest() throws Exception {
    Mockito.when(player.getWeapon()).thenReturn("Sword");

    enemies.add("Dragon");
    enemies.add("Orc");

    assertEquals(2, game.numberOfEnemies());

    assertEquals("Player attack with: Sword", game.attack());
  }
}

class Game {

  private Player player;

  private List<String> opponents;

  public Game(Player player, List<String> opponents) {
    this.player = player;
    this.opponents = opponents;
  }

  public int numberOfEnemies() {
    return opponents.size();
  }

  // ...

এটি কারণ মকিতো Type Signatureগেম ক্লাসের পরীক্ষা করবে , যা Playerএবং List<String>


16
এই উদাহরণ সহ এটি গ্রহণযোগ্য উত্তর হওয়া উচিত।
আনা ক্লেইন

4
আমার মনে হয় এটিও সেরা উত্সাহী
এভেজেনি ডোরোফিভ

4
আমি মনে করি এটি সেরা উত্তর ট্রিপল।
হার্ভি ডেন্ট

1
আমি মাঝে মাঝে একটি ক্লাসের জন্য বুঝতে এবং নকশাকে শক্ত করে উপহাসের সাথে টেস্টিংটি পাই। তবে এই উদাহরণটি ওভারভিউ সরবরাহ করতে অনেক সহায়তা করে helps
চাকলাদার আসফাক আরেফে

1
অনেক ধন্যবাদ :) আরও ভাল ব্যাখ্যার সাথে।
ঋষি

80

আপনার পরীক্ষার ক্লাসে, পরীক্ষিত শ্রেণীর সাথে টিকা দেওয়া উচিত @InjectMocks। এটি মকিতোকে বলে যে কোন শ্রেণিতে মক ইনজেকশন করা উচিত:

@InjectMocks
private SomeManager someManager;

তারপরে, আমরা শ্রেণীর অভ্যন্তরে কোন নির্দিষ্ট পদ্ধতি বা অবজেক্টগুলি সুনির্দিষ্ট করতে পারি, এই ক্ষেত্রে, SomeManagerউপহাসের পরিবর্তে প্রতিস্থাপন করা হবে:

@Mock
private SomeDependency someDependency;

এই উদাহরণে, শ্রেণীর SomeDependencyভিতরে SomeManagerউপহাস করা হবে।


6
এই কাজটি যদি কোনও ম্যানেজারের আরও একজন কনস্ট্রাক্টর থাকে? যদি কোনও ম্যানেজারের 5 জন কনস্ট্রাক্টর থাকে তবে এটি কীভাবে জানতে পারে আপনি কোনটি ব্যবহার করতে চান?
j2emanue

51

@Mock টীকা সম্পর্কিত বিষয়টিকে ব্যঙ্গ করে।

@InjectMocksটীকাগুলি অন্তর্নিহিত অবজেক্টের দ্বারা তৈরি করা বিভিন্ন (এবং প্রাসঙ্গিক) উপহাসকে মঞ্জুরি দেয় @Mock

দুটোই পরিপূরক।


1
তারা কি একই বস্তুতে টেন্ডেম ব্যবহার করা যেতে পারে?
ইগোরগানাপলস্কি

1
আপনার কি আপনার প্রয়োজনের একটি মিনি উদাহরণ রয়েছে?
Mik378

আমার একটি ক্লাস রয়েছে যার জন্য মকিতো স্পাইয়ের মাধ্যমে গুপ্তচরবৃত্তি করা দরকার এবং এই শ্রেণীর একজন কনস্ট্রাক্টর রয়েছে। সুতরাং আমি @InjectMocksএই ক্লাসটি তৈরি করতে এবং এটিতে গুপ্তচরবৃত্তি ব্যবহার করার কথা ভাবছিলাম ।
ইগোরগানাপলস্কি

1
আপনি কি এটি খুঁজছেন? stackoverflow.com/a/35969166/985949
Mik378

23
  • @ মোক আপনার প্রয়োজনীয় ক্লাসগুলির জন্য একটি মক বাস্তবায়ন তৈরি করে।
  • @ ইনজেক্টমক ক্লাসের একটি উদাহরণ তৈরি করে এবং তাতে টীকাগুলি চিহ্নযুক্ত মকগুলকে ইনজেকশন দেয় @ এটিতে মক করুন

উদাহরণ স্বরূপ

@Mock
StudentDao studentDao;

@InjectMocks
StudentService service;

@Before
public void setUp() throws Exception {
    MockitoAnnotations.initMocks(this);
}

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

MockitoAnnotations.initMocks(this)পদ্ধতি এই মকগুলিকে আরম্ভ করে এবং প্রতিটি পরীক্ষার পদ্ধতির জন্য সেগুলিকে সংক্রামিত করে তাই এটি পদ্ধতিতে ডাকতে হবে setUp()

এই লিঙ্কটিতে মকিতো কাঠামোর জন্য একটি ভাল টিউটোরিয়াল রয়েছে


13

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

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

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

@InjectMocksটীকা পরীক্ষামূলক বস্তুর উদাহরণস্বরূপ এবং উদ্বুদ্ধ ক্ষেত্রের সাথে সটীক instantiate করার চেষ্টা করে @Mockবা @Spyপরীক্ষামূলক বস্তুর ব্যক্তিগত ক্ষেত্রগুলির মধ্যে।

MockitoAnnotations.initMocks(this)কল করুন, টেস্টিং অবজেক্টটিকে পুনরায় সেট করুন এবং উপহাসকে পুনরায় সূচনা করুন, সুতরাং আপনার @Before/ @BeforeMethodটিকাতে এটি মনে রাখবেন ।


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

10

@ টম দ্বারা উল্লিখিত পদ্ধতির সাথে আপনি যে সুবিধাটি পেয়েছেন তা হ'ল সোমারম্যানেজারে আপনাকে কোনও নির্মাণকারী তৈরি করতে হবে না, এবং তাই ক্লায়েন্টদের এটি ইনস্ট্যান্ট করতে সীমাবদ্ধ।

@RunWith(MockitoJUnitRunner.class)
public class SomeManagerTest {

    @InjectMocks
    private SomeManager someManager;

    @Mock
    private SomeDependency someDependency; // this will be injected into someManager

    //You don't need to instantiate the SomeManager with default contructor at all
   //SomeManager someManager = new SomeManager();    
   //Or SomeManager someManager = new SomeManager(someDependency);

     //tests...

}

এটি একটি ভাল অনুশীলন কিনা তা আপনার অ্যাপ্লিকেশন ডিজাইনের উপর নির্ভর করে।


যদি কোনও ম্যানেজারের 3 টি আলাদা কনস্ট্রাক্টর থাকে তবে এটি কীভাবে ব্যবহার করবেন তা কীভাবে জানবেন?
j2emanue

যদি কোনও ম্যানেজারের উপহাস না করা হয় তবে আপনি কীভাবে তা যাচাই করবেন ?
ইগোরগানাপলস্কি

5

@Mockবনাম সম্পর্কে অনেক লোক এখানে দুর্দান্ত ব্যাখ্যা দিয়েছেন @InjectMocks। আমি এটি পছন্দ করি তবে আমি মনে করি আমাদের পরীক্ষাগুলি এবং অ্যাপ্লিকেশনটি এমনভাবে লেখা উচিত যাতে আমাদের ব্যবহারের প্রয়োজন হবে না @InjectMocks

উদাহরণ সহ আরও পড়ার জন্য রেফারেন্স: https://tedvinke.wordpress.com/2014/02/13/mockito-why-you-should-not-use-injectmocks-nnotation-to-autowire-fields/


1
এটি একটি দীর্ঘমেয়াদী সমাধান বলে মনে হচ্ছে।
বিনয়াক দোরণালা

4

@Mockনির্ভরশীল শিমের রেফারেন্সগুলি ঘোষিত / উপহাস করার @InjectMocksজন্য ব্যবহৃত হয়, এবং শিমকে উপহাস করার জন্য ব্যবহার করা হয় যার জন্য পরীক্ষা তৈরি করা হচ্ছে।

উদাহরণ স্বরূপ:

public class A{

   public class B b;

   public void doSomething(){

   }

}

শ্রেণীর জন্য পরীক্ষা A:

public class TestClassA{

   @Mocks
   public class B b;

   @InjectMocks
   public class A a;

   @Test
   public testDoSomething(){

   }

}

4

@ ইনজেক্টমোকস টীকাটি স্বয়ংক্রিয়ভাবে কোনও পরীক্ষামূলক বস্তুতে মক ক্ষেত্রগুলি ইনজেক্ট করতে ব্যবহার করা যেতে পারে।

নীচের উদাহরণে @ ইনজেক্টমকস মক ডেটা ম্যাপটিকে ইনজেক্ট করতে ব্যবহার করেছেন ডেটা লাইব্রায়িতে।

@Mock
Map<String, String> dataMap ;

@InjectMocks
DataLibrary dataLibrary = new DataLibrary();


    @Test
    public void whenUseInjectMocksAnnotation_() {
        Mockito.when(dataMap .get("aData")).thenReturn("aMeaning");

        assertEquals("aMeaning", dataLibrary .getMeaning("aData"));
    }

3

লক্ষ্য করুন যে সেগুলি @InjectMocksহ্রাস পেতে চলেছে

@ ইনজেক্টমোকস অবহেলা করুন এবং মকিতো 3/4 এ অপসারণের সময়সূচী

এবং আপনি @Avp উত্তর অনুসরণ এবং লিঙ্ক করতে পারেন :

আপনার ক্ষেত্রগুলিকে স্বীকৃতি দেওয়ার জন্য কেন ইনজেকশন মোকস টিকা ব্যবহার করা উচিত নয়


3

যদিও উপরের উত্তরগুলি কভার করেছে, আমি কেবল মিনিট বিশদ যুক্ত করার চেষ্টা করেছি যা আমি অনুপস্থিত দেখছি। তাদের পিছনে কারণ (কেন)।

এখানে চিত্র বর্ণনা লিখুন


চিত্রণ:

Sample.java
---------------
    public class Sample{
        DependencyOne dependencyOne;
        DependencyTwo dependencyTwo;


        public SampleResponse methodOfSample(){
            dependencyOne.methodOne();
            dependencyTwo.methodTwo();

            ...

            return sampleResponse;
        }
    }

SampleTest.java
-----------------------
@RunWith(PowerMockRunner.class)
@PrepareForTest({ClassA.class})
public class SampleTest{

    @InjectMocks
    Sample sample;

    @Mock
    DependencyOne dependencyOne;

    @Mock
    DependencyTwo dependencyTwo;

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

    public void sampleMethod1_Test(){
        //Arrange the dependencies
        DependencyResponse dependencyOneResponse = Mock(sampleResponse.class);
        Mockito.doReturn(dependencyOneResponse).when(dependencyOne).methodOne();

        DependencyResponse dependencyTwoResponse = Mock(sampleResponse.class);
        Mockito.doReturn(dependencyOneResponse).when(dependencyTwo).methodTwo();

        //call the method to be tested
        SampleResponse sampleResponse = sample.methodOfSample() 

        //Assert
        <assert the SampleResponse here>
    }
}

উল্লেখ

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