মকিতো দিয়ে কীভাবে শূন্য পদ্ধতিগুলি উপহাস করবেন


936

অকার্যকর রিটার্ন টাইপের সাথে কীভাবে উপহাসের পদ্ধতিগুলি?

আমি একটি পর্যবেক্ষক প্যাটার্ন বাস্তবায়ন করেছি তবে আমি এটি মকিতো দিয়ে উপহাস করতে পারছি না কারণ আমি জানি না।

এবং আমি ইন্টারনেটে একটি উদাহরণ সন্ধান করার চেষ্টা করেছি কিন্তু সফল হই নি।

আমার ক্লাসটি এমন দেখাচ্ছে:

public class World {

    List<Listener> listeners;

    void addListener(Listener item) {
        listeners.add(item);
    }

    void doAction(Action goal,Object obj) {
        setState("i received");
        goal.doAction(obj);
        setState("i finished");
    }

    private string state;
    //setter getter state
} 

public class WorldTest implements Listener {

    @Test public void word{
    World  w= mock(World.class);
    w.addListener(this);
    ...
    ...

    }
}

interface Listener {
    void doAction();
}

মক দিয়ে সিস্টেমটি ট্রিগার করা হয় না।

আমি উপরে বর্ণিত সিস্টেমের অবস্থাটি প্রদর্শন করতে চাই। এবং তাদের অনুসারে জোর দেওয়া।


6
সাবধান থাকুন যে বিদ্রূপের শূন্য পদ্ধতিগুলি ডিফল্টরূপে কিছু না করে!
লাইনে

1
@ লাইন, আমি যা খুঁজছিলাম আপনি এটি বলার পরে এটি স্পষ্ট বলে মনে হচ্ছে। তবে এটি একটি বিদ্রূপাত্মক নীতিটি হাইলাইট করে: আপনার কেবলমাত্র প্রত্যাবর্তন মূল্য বা একটি ব্যতিক্রমের মতো প্রভাবগুলির জন্য উপহাসের ক্লাসগুলির পদ্ধতিগুলি উপহাস করা উচিত। ধন্যবাদ!
অ্যালেনজম

উত্তর:


1144

মকিটো এপিআই ডক্সটি একবার দেখুন । লিঙ্ক ডকুমেন্ট উল্লেখ হিসাবে (পয়েন্ট # 12) আপনি কোন ব্যবহার করতে পারেন doThrow(), doAnswer(), doNothing(), doReturn()Mockito ফ্রেমওয়ার্ক থেকে পদ্ধতির পরিবার অকার্যকর পদ্ধতি উপহাস।

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

Mockito.doThrow(new Exception()).when(instance).methodName();

বা যদি আপনি এটিকে ফলো-আপ আচরণের সাথে একত্রিত করতে চান,

Mockito.doThrow(new Exception()).doNothing().when(instance).methodName();

অনুমান করে আপনি setState(String s)নীচের ক্লাস ওয়ার্ল্ডে সেটারকে বিদ্রূপ করতে দেখছেন কোডটি হ'ল doAnswerউপহাস করার জন্য পদ্ধতিটি ব্যবহার করে setState

World  mockWorld = mock(World.class); 
doAnswer(new Answer<Void>() {
    public Void answer(InvocationOnMock invocation) {
      Object[] args = invocation.getArguments();
      System.out.println("called with arguments: " + Arrays.toString(args));
      return null;
    }
}).when(mockWorld).setState(anyString());

8
@ কালিডিফায়াল: হ্যাঁ, আমি মনে করি ভয়েডের প্যারামিটারাইজেশনটি আরও ভাল হবে কারণ এটি আরও ভালভাবে জানায় যে আমি ফেরতের ধরণের বিষয়ে আগ্রহী নই। আমি এই নির্মাণ সম্পর্কে সচেতন ছিলাম না, এটি নির্দেশ করার জন্য ধন্যবাদ।
সতীশ

2
doThrow এখন # 5 (আমার জন্য doThrow এটিও এই বার্তাটি "'বাতিল' টাইপ করার অনুমতি নেই এখানে, অনুগামীদের জন্য ...)
রজারডপ্যাক

@ কালিডিফায়াল: আমি মনে করি যে উত্তর.সানওয়ার কলের রিটার্নের ধরণটি মূল পদ্ধতিতে ফিরে আসে না, এটিই ডুঅ্যাঞ্জার কলটিতে ফিরে আসে, সম্ভবত আপনি যদি পরীক্ষায় সেই মানটি দিয়ে অন্য কিছু করতে চান তবে সম্ভবত।
বারো 17

1
:( পেয়ারা ডোনিংথিং-এ কিছুই নেই) এর রেটলিমিটার.জাগা এর ১ 16.০.১ সংস্করণে মক করার চেষ্টা করার সময়। (যখন মকলিমিটাররেজেক্ট)। সেটরেট (১০০) রেটলিমিটারের তেহর সেটট্রেট কল করার ফলে ফলশ্রুতিতে একসময় মকিটোকো বাইকোড করা হয়েছে যেহেতু মুটেক্স কোনও কারণে নালপয়েন্টার বাতিল হয় since এটি তাই এটি আমার সেটরেট পদ্ধতিটিকে উপহাস করে না :( পরিবর্তে এটি বলে :(
ডিন হিলার

2
@ ডিয়ানহিলার বিজ্ঞপ্তিটি setRate()হ'ল final, এবং তাই উপহাস করা যায় না। পরিবর্তে create()একটি উদাহরণ চেষ্টা করে দেখুন যা আপনার প্রয়োজন অনুযায়ী করে। উপহাস করার দরকার নেই RateLimiter
ডিমো 414

113

আমি মনে করি কেবলমাত্র একটি পদ্ধতির জন্য আসল পদ্ধতিটি কল করতে আমি এই প্রশ্নের সহজ উত্তর পেয়েছি (যদিও এটির অকার্যকর রিটার্ন থাকলেও) আপনি এটি করতে পারেন:

Mockito.doCallRealMethod().when(<objectInstance>).<method>();
<objectInstance>.<method>();

অথবা, আপনি এই শ্রেণীর সমস্ত পদ্ধতির জন্য প্রকৃত পদ্ধতিটি কল করতে পারেন, এটি করে:

<Object> <objectInstance> = mock(<Object>.class, Mockito.CALLS_REAL_METHODS);

13
এই মুহূর্তে আসল উত্তর। গুপ্তচর () পদ্ধতিটি ঠিকঠাকভাবে কাজ করে, তবে আপনি যখন সাধারণত অবজেক্টটিকে সর্বাধিক সবকিছু করতে চান তখন সাধারণত তার জন্য সংরক্ষিত থাকে।
biggusjimmus

1
এটার মানে কি? আপনি কি আসলে পদ্ধতিগুলি কল করছেন? আমি সত্যিই এর আগে মকিতো ব্যবহার করি নি।
নিবিড় চিকেন 13

হ্যাঁ, মোক প্রকৃত পদ্ধতিগুলি কল করবে। আপনি যদি @ মক ব্যবহার করেন তবে একই ফলাফলগুলি পেতে আপনি: @ মক (উত্তর = উত্তরসমূহ AL কল LSALAL_METHODS) এর সাথে একইটি নির্দিষ্ট করতে পারেন।
এলে

70

@ সীতেশ যা বলেছিলেন তাতে যোগ করে, যখন আপনি পরীক্ষাটি কল করা থেকে বিরত রাখতে কেবল একটি শূন্য পদ্ধতিটি উপহাস করতে চান, আপনি Spyএইভাবে ব্যবহার করতে পারেন :

World world = new World();
World spy = Mockito.spy(world);
Mockito.doNothing().when(spy).methodToMock();

আপনি আপনার পরীক্ষার চালাতে চান, তখন কি নিশ্চিতরূপে উপর পরীক্ষা পদ্ধতি কল করুন spyবস্তু এবং না worldঅবজেক্ট। উদাহরণ স্বরূপ:

assertEquals(0,spy.methodToTestThatShouldReturnZero());

57

তথাকথিত সমস্যার সমাধান হ'ল মকিতো.মক (..) এর পরিবর্তে একটি spy মকিতো.স্পাই (...) ব্যবহার করা ।mock

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


3
আমি এখানে হোঁচট খেয়েছি কারণ আমারও একই সমস্যা ছিল (এছাড়াও, কাকতালীয়ভাবে, একটি সাবজেক্ট / অবজারভার ইন্টারঅ্যাকশন পরীক্ষা করে দেখেছি)। আমি ইতিমধ্যে একটি গুপ্তচর ব্যবহার করছি তবে আমি 'সাবজেক্ট চেঞ্জড' পদ্ধতিটি কিছু আলাদা করতে চাই। আমি `যাচাই (পর্যবেক্ষক) .সুবজেক্ট চেঞ্জড (বিষয়) কেবল পদ্ধতিটি বলা হয়েছিল তা দেখতে ব্যবহার করতে পারি। তবে, কোনও কারণে আমি এই পদ্ধতিটিকে অনেক বেশি অগ্রাহ্য করব। তার জন্য,
সতীশের

32
না, এটি করার ফলে অকার্যকর পদ্ধতিগুলিকে ঠাট্টা-বিদ্রূপ করতে আসলে সহায়তা করবে না। কৌশলটি হ'ল সতীশের উত্তরে তালিকাভুক্ত চারটি মকিতো স্থিত পদ্ধতি ব্যবহার করা।
দাউদ ইবনে করিম

2
আপনার প্রশ্নের জন্য @Gurnard এই কটাক্ষপাত করা stackoverflow.com/questions/1087339/...
ইব্রাহিমিলাজম

এই নীরবতা আসলে কাজ করে।
নিলোটপাল

34

প্রথমত: আপনার সর্বদা মকিতো স্ট্যাটিক আমদানি করা উচিত, এইভাবে কোডটি আরও বেশি পঠনযোগ্য (এবং স্বজ্ঞাত) হবে:

import static org.mockito.Mockito.*;

আংশিক উপহাস করার জন্য এবং এখনও বাকি মকিতোতে "স্পাই" অফার করে মূল কার্যকারিতা রাখার জন্য।

আপনি নিম্নলিখিত হিসাবে এটি ব্যবহার করতে পারেন:

private World world = spy(World.class);

কোনও পদ্ধতি কার্যকর হওয়ার থেকে বাদ দিতে আপনি এই জাতীয় কিছু ব্যবহার করতে পারেন:

doNothing().when(someObject).someMethod(anyObject());

কোনও পদ্ধতিতে কিছু কাস্টম আচরণ দেওয়ার জন্য "যখন" তখন "পুনরায়" সাথে ব্যবহার করুন:

doReturn("something").when(this.world).someMethod(anyObject());

আরও উদাহরণের জন্য দয়া করে দস্তাবেজে দুর্দান্ত মকিতো নমুনাগুলি সন্ধান করুন।


4
এটিকে আরও পঠনযোগ্য করে তোলার সাথে স্ট্যাটিক আমদানির কী সম্পর্ক রয়েছে?
jsonbourne

2
আক্ষরিক কিছুই।
বিশেষায়িত করুন

2
আমি মনে করি এটি স্বাদের বিষয়, আমি কেবলমাত্র একটি ইংরেজি বাক্যটির মতো বিবৃতি দেখতে (প্রায়) দেখতে চাই এবং ক্লাস.মোথডমনাম () কিছু () বনাম পদ্ধতি নাম ()। কিছু কম তরল পদার্থ পাঠযোগ্য নয়।
fl0w

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

এটি সঠিক, তবে টেস্ট কোড এবং মকিতোর ক্ষেত্রে এটি সুস্পষ্ট হওয়া উচিত এবং কোনও সমস্যা নয়।
fl0w

26

মকিটো দিয়ে শূন্য পদ্ধতিগুলি কীভাবে উপহাস করবেন - দুটি বিকল্প রয়েছে:

  1. doAnswer - আমরা যদি আমাদের উপহাস শূন্য পদ্ধতিতে কিছু করতে চাই (শূন্য থাকা সত্ত্বেও আচরণকে বিদ্রূপ করুন)।
  2. doThrow- তারপরেও Mockito.doThrow()যদি আপনি মশকরা শূন্য পদ্ধতি থেকে একটি ব্যতিক্রম ছুঁড়ে দিতে চান।

এটি কীভাবে ব্যবহার করা যায় তার উদাহরণ নীচে দেওয়া হয়েছে (আদর্শ ব্যবহারের হাতছাড়া নয় তবে কেবল প্রাথমিক ব্যবহারটি চিত্রিত করতে চেয়েছিলেন)।

@Test
public void testUpdate() {

    doAnswer(new Answer<Void>() {

        @Override
        public Void answer(InvocationOnMock invocation) throws Throwable {
            Object[] arguments = invocation.getArguments();
            if (arguments != null && arguments.length > 1 && arguments[0] != null && arguments[1] != null) {

                Customer customer = (Customer) arguments[0];
                String email = (String) arguments[1];
                customer.setEmail(email);

            }
            return null;
        }
    }).when(daoMock).updateEmail(any(Customer.class), any(String.class));

    // calling the method under test
    Customer customer = service.changeEmail("old@test.com", "new@test.com");

    //some asserts
    assertThat(customer, is(notNullValue()));
    assertThat(customer.getEmail(), is(equalTo("new@test.com")));

}

@Test(expected = RuntimeException.class)
public void testUpdate_throwsException() {

    doThrow(RuntimeException.class).when(daoMock).updateEmail(any(Customer.class), any(String.class));

    // calling the method under test
    Customer customer = service.changeEmail("old@test.com", "new@test.com");

}
}

আমার পোস্টে মকিতোর সাথে কীভাবে বিদ্রূপ করা এবং শূন্য পদ্ধতিগুলি পরীক্ষা করা যায় সে সম্পর্কে আপনি আরও বিবরণ পেতে পারেন কিভাবে মকিতো দিয়ে উপহাস করবেন (উদাহরণ সহ একটি বিস্তৃত গাইড)


1
দুর্দান্ত উদাহরণ। দ্রষ্টব্য: জাভা 8-তে, কোনও বেনাম শ্রেণীর পরিবর্তে ল্যাম্বডা ব্যবহার করা কিছুটা ভাল হতে পারে: 'doAnswer ((উত্তর <অবধি>) অনুরোধ -> {// CODE})। যখন (মকআইএনস্ট্যান্স) .এডিডি (পদ্ধতি) ()); '
মিইউ

16

গুচ্ছের কাছে আরও একটি উত্তর যুক্ত করা হচ্ছে (কোনও পাং উদ্দেশ্য নয়) ...

আপনি গুপ্তচর ব্যবহার করতে না চাইলে আপনাকে doAnswer পদ্ধতিতে কল করতে হবে। তবে অগত্যা আপনার নিজের উত্তরটি রোল করার দরকার নেই । বেশ কয়েকটি ডিফল্ট বাস্তবায়ন রয়েছে। উল্লেখযোগ্যভাবে, কল রিলেমথোডস

অনুশীলনে, এটি দেখতে এরকম কিছু দেখাচ্ছে:

doAnswer(new CallsRealMethods()).when(mock)
        .voidMethod(any(SomeParamClass.class));

বা:

doAnswer(Answers.CALLS_REAL_METHODS.get()).when(mock)
        .voidMethod(any(SomeParamClass.class));

16

জাভা 8 এ আপনার কাছে স্ট্যাটিক আমদানি রয়েছে বলে ধরে নিয়ে এইটিকে একটু পরিষ্কার করা যায় org.mockito.Mockito.doAnswer:

doAnswer(i -> {
  // Do stuff with i.getArguments() here
  return null;
}).when(*mock*).*method*(*methodArguments*);

return null;গুরুত্বপূর্ণ এবং এটা ছাড়া কম্পাইল কিছু মোটামুটি অখ্যাত ত্রুটিযুক্ত ব্যর্থ হবে যেমন এটির জন্য একটি উপযুক্ত ওভাররাইড খুঁজে পেতে সক্ষম হবেন না doAnswer

উদাহরণস্বরূপ একটি ExecutorServiceযা কেবল অবিলম্বে কার্যকর Runnableকরা execute()হতে পারে যে কোনও পাস কার্যকর করে:

doAnswer(i -> {
  ((Runnable) i.getArguments()[0]).run();
  return null;
}).when(executor).execute(any());

2
এক লাইনে: মকিতো.ডোআনসওয়ার ((i) -> নাল) hen
অক্ষয় থর্ভ

@ অক্ষয়থোরভে আপনি যখন আমার সাথে আসলে কাজ করতে চান তখন তা কার্যকর হয় না।
টিম বি

7

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

আপনি যদি শ্রোতাকে মোক হিসাবে কার্যকর করেন তবে আপনি ইন্টারঅ্যাকশনটি যাচাই করতে পারবেন।

Listener listener = mock(Listener.class);
w.addListener(listener);
world.doAction(..);
verify(listener).doAction();

এটি আপনাকে সন্তুষ্ট করা উচিত যে 'ওয়ার্ল্ড' সঠিক কাজ করছে।


0

মকিতো.ডো থ্রোকে এই হিসাবে ব্যবহার করুন:

Mockito.doThrow(new Exception()).when(instance).methodName();

আপনি এই চমৎকার উদাহরণ চেষ্টা করতে পারেন:

public void testCloseStreamOnException() throws Exception {
    OutputStream outputStream = Mockito.mock(OutputStream.class);
    IFileOutputStream ifos = new IFileOutputStream(outputStream);
    Mockito.doThrow(new IOException("Dummy Exception")).when(outputStream).flush();
    try {
      ifos.close();
      fail("IOException is not thrown");
    } catch (IOException ioe) {
      assertEquals("Dummy Exception", ioe.getMessage());
    }
    Mockito.verify(outputStream).close();
  }

সূত্র: http://apisonar.com/java-example/org.mockito.Mockito.doThrow.html#Example-19

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