মকিতো কাঠামোর মধ্যে @Mock
এবং এর @InjectMocks
মধ্যে পার্থক্য কী ?
মকিতো কাঠামোর মধ্যে @Mock
এবং এর @InjectMocks
মধ্যে পার্থক্য কী ?
উত্তর:
@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...
}
এই কীভাবে একটি নমুনা কোড @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>
।
আপনার পরীক্ষার ক্লাসে, পরীক্ষিত শ্রেণীর সাথে টিকা দেওয়া উচিত @InjectMocks
। এটি মকিতোকে বলে যে কোন শ্রেণিতে মক ইনজেকশন করা উচিত:
@InjectMocks
private SomeManager someManager;
তারপরে, আমরা শ্রেণীর অভ্যন্তরে কোন নির্দিষ্ট পদ্ধতি বা অবজেক্টগুলি সুনির্দিষ্ট করতে পারি, এই ক্ষেত্রে, SomeManager
উপহাসের পরিবর্তে প্রতিস্থাপন করা হবে:
@Mock
private SomeDependency someDependency;
এই উদাহরণে, শ্রেণীর SomeDependency
ভিতরে SomeManager
উপহাস করা হবে।
@Mock
টীকা সম্পর্কিত বিষয়টিকে ব্যঙ্গ করে।
@InjectMocks
টীকাগুলি অন্তর্নিহিত অবজেক্টের দ্বারা তৈরি করা বিভিন্ন (এবং প্রাসঙ্গিক) উপহাসকে মঞ্জুরি দেয় @Mock
।
দুটোই পরিপূরক।
@InjectMocks
এই ক্লাসটি তৈরি করতে এবং এটিতে গুপ্তচরবৃত্তি ব্যবহার করার কথা ভাবছিলাম ।
উদাহরণ স্বরূপ
@Mock
StudentDao studentDao;
@InjectMocks
StudentService service;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
}
এখানে আমাদের পরিষেবা ক্লাসের জন্য ডিএও ক্লাস প্রয়োজন। সুতরাং, আমরা এটি উপহাস করি এবং এটি পরিষেবা শ্রেণির উদাহরণে ইনজেক্ট করি। একইভাবে, স্প্রিং ফ্রেমওয়ার্কে সমস্ত @ অটোভায়ার্ড শিমকে জুনিতগুলিতে @ মক দ্বারা বিদ্রূপ করা যায় এবং @ ইনজেক্টমোকসের মাধ্যমে আপনার শিমের মধ্যে ইনজেকশনের ব্যবস্থা করা যেতে পারে।
MockitoAnnotations.initMocks(this)
পদ্ধতি এই মকগুলিকে আরম্ভ করে এবং প্রতিটি পরীক্ষার পদ্ধতির জন্য সেগুলিকে সংক্রামিত করে তাই এটি পদ্ধতিতে ডাকতে হবে setUp()
।
মকিতো ভিত্তিক একটি "মজাদার কাঠামো" হ'ল একটি কাঠামো যা আপনাকে মক অবজেক্ট তৈরি করার দক্ষতা দেয় (পুরানো ভাষায় এই বিষয়গুলিকে শান্ট বলা যেতে পারে, কারণ তারা নির্ভরশীল কার্যকারিতার জন্য শান্ট হিসাবে কাজ করে) অন্য কথায়, একটি উপহাস আপনার কোড নির্ভর করে এমন সত্যিকারের অবজেক্টটি অনুকরণ করতে অবজেক্টটি ব্যবহার করা হয়, আপনি বিদ্রূপের কাঠামোর সাহায্যে একটি প্রক্সি অবজেক্ট তৈরি করেন। আপনার পরীক্ষাগুলিতে মক অবজেক্টগুলি ব্যবহার করে আপনি প্রয়োজনীয়ভাবে সাধারণ ইউনিট টেস্টিং থেকে ইন্টিগ্রেশনাল টেস্টিংয়ে যাচ্ছেন
এমকিআইটি লাইসেন্সের আওতায় প্রকাশিত জাভার জন্য মকিতো একটি ওপেন সোর্স টেস্টিং ফ্রেমওয়ার্ক, এটি একটি "মজাদার ফ্রেমওয়ার্ক", যা আপনাকে পরিষ্কার এবং সাধারণ এপিআই দিয়ে সুন্দর পরীক্ষা লিখতে দেয়। জাভা স্পেসে অনেকগুলি বিদ্রূপমূলক ফ্রেমওয়ার্ক রয়েছে তবে মূলত দুটি প্রধান ধরণের মক অবজেক্ট ফ্রেমওয়ার্ক রয়েছে, যা প্রক্সি এবং ক্লাস রিম্যাপিংয়ের মাধ্যমে প্রয়োগ করা হয় এর মাধ্যমে প্রয়োগ করা হয়।
স্প্রিংয়ের মতো নির্ভরতা ইনজেকশন ফ্রেমওয়ার্কগুলি আপনাকে কোনও কোড পরিবর্তন না করেই আপনার প্রক্সি অবজেক্টগুলি ইনজেকশনের অনুমতি দেয়, মক অবজেক্টটি একটি নির্দিষ্ট পদ্ধতিটি কল করার প্রত্যাশা করে এবং এটি প্রত্যাশিত ফলাফল প্রত্যাবর্তন করে।
@InjectMocks
টীকা পরীক্ষামূলক বস্তুর উদাহরণস্বরূপ এবং উদ্বুদ্ধ ক্ষেত্রের সাথে সটীক instantiate করার চেষ্টা করে @Mock
বা @Spy
পরীক্ষামূলক বস্তুর ব্যক্তিগত ক্ষেত্রগুলির মধ্যে।
MockitoAnnotations.initMocks(this)
কল করুন, টেস্টিং অবজেক্টটিকে পুনরায় সেট করুন এবং উপহাসকে পুনরায় সূচনা করুন, সুতরাং আপনার @Before
/ @BeforeMethod
টিকাতে এটি মনে রাখবেন ।
@ টম দ্বারা উল্লিখিত পদ্ধতির সাথে আপনি যে সুবিধাটি পেয়েছেন তা হ'ল সোমারম্যানেজারে আপনাকে কোনও নির্মাণকারী তৈরি করতে হবে না, এবং তাই ক্লায়েন্টদের এটি ইনস্ট্যান্ট করতে সীমাবদ্ধ।
@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...
}
এটি একটি ভাল অনুশীলন কিনা তা আপনার অ্যাপ্লিকেশন ডিজাইনের উপর নির্ভর করে।
@Mock
বনাম সম্পর্কে অনেক লোক এখানে দুর্দান্ত ব্যাখ্যা দিয়েছেন @InjectMocks
। আমি এটি পছন্দ করি তবে আমি মনে করি আমাদের পরীক্ষাগুলি এবং অ্যাপ্লিকেশনটি এমনভাবে লেখা উচিত যাতে আমাদের ব্যবহারের প্রয়োজন হবে না @InjectMocks
।
উদাহরণ সহ আরও পড়ার জন্য রেফারেন্স: https://tedvinke.wordpress.com/2014/02/13/mockito-why-you-should-not-use-injectmocks-nnotation-to-autowire-fields/
@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(){
}
}
@ ইনজেক্টমোকস টীকাটি স্বয়ংক্রিয়ভাবে কোনও পরীক্ষামূলক বস্তুতে মক ক্ষেত্রগুলি ইনজেক্ট করতে ব্যবহার করা যেতে পারে।
নীচের উদাহরণে @ ইনজেক্টমকস মক ডেটা ম্যাপটিকে ইনজেক্ট করতে ব্যবহার করেছেন ডেটা লাইব্রায়িতে।
@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"));
}
যদিও উপরের উত্তরগুলি কভার করেছে, আমি কেবল মিনিট বিশদ যুক্ত করার চেষ্টা করেছি যা আমি অনুপস্থিত দেখছি। তাদের পিছনে কারণ (কেন)।
চিত্রণ:
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>
}
}