মকিতো: doAnswer Vs thenReturn


124

আমি পরে ইউনিট পরীক্ষার জন্য মকিতো ব্যবহার করছি। doAnswerবনাম ব্যবহার করার সময় আমি বিভ্রান্ত হয়ে পড়েছি thenReturn

কেউ আমাকে বিশদে সাহায্য করতে পারেন? এখনও অবধি চেষ্টা করেছি thenReturn

উত্তর:


167

আপনি ব্যবহার করা উচিত thenReturnবা doReturnযখন আপনি সময়ে ফেরত মান জানি তুমি একটি পদ্ধতি কল উপহাস। আপনি বিদ্রূপিত পদ্ধতিতে অনুরোধ করলে এই সংজ্ঞায়িত মানটি ফিরে আসে।

thenReturn(T value) পদ্ধতিটি যখন ডাকা হবে তখন ফেরতের জন্য একটি ফেরতের মান সেট করে।

@Test
public void test_return() throws Exception {
    Dummy dummy = mock(Dummy.class);
    int returnValue = 5;

    // choose your preferred way
    when(dummy.stringLength("dummy")).thenReturn(returnValue);
    doReturn(returnValue).when(dummy).stringLength("dummy");
}

Answer যখন কোনও উপহাস পদ্ধতিটি চালু করা হয় যখন আপনাকে অতিরিক্ত ক্রিয়াকলাপ করার দরকার হয় তখন ব্যবহৃত হয়, উদাহরণস্বরূপ যখন আপনাকে এই পদ্ধতি কলের পরামিতিগুলির উপর ভিত্তি করে রিটার্ন মান গণনা করতে হবে।

doAnswer()যখন আপনি জেনেরিকের সাথে একটি অকার্যকর পদ্ধতিতে স্টাব করতে চান তখন ব্যবহার করুন Answer

উত্তরটি এমন একটি ক্রিয়াকলাপ নির্দিষ্ট করে যা কার্যকর করা হয় এবং একটি প্রতিক্রিয়ার মান যা আপনি উপহাসের সাথে ইন্টারঅ্যাক্ট করার সময় ফিরে আসে।

@Test
public void test_answer() throws Exception {
    Dummy dummy = mock(Dummy.class);
    Answer<Integer> answer = new Answer<Integer>() {
        public Integer answer(InvocationOnMock invocation) throws Throwable {
            String string = invocation.getArgumentAt(0, String.class);
            return string.length() * 2;
        }
    };

    // choose your preferred way
    when(dummy.stringLength("dummy")).thenAnswer(answer);
    doAnswer(answer).when(dummy).stringLength("dummy");
}

হাই @ রোল্যান্ড উইজল্ডার তবে কখনও কখনও আপনার কিছু মান উত্পন্ন অভ্যন্তরীণ কোড এবং যুক্তির সাথে কিছুই করার দরকার নেই, উদাহরণস্বরূপ code = UUID.randomUUID(), এটির সাথে প্রয়োগ করা আমার পক্ষে অসম্ভব বলে মনে হয়েছিল mockito
zhuguowei

3
যখন আপনার বিদ্রূপটি প্রতিটি অনুরোধের জন্য একটি নতুন ইউইউডি ফিরিয়ে দেবে আপনি Answerঠিক সেই সাথে বাস্তবায়ন করবেন return UUID.randomUUID();
রোল্যান্ড ওয়েসল্ডার

কোডটি আরও কিছুটা পরিষ্কার করার জন্য, আমি কি নতুন উত্তর সূচনা থেকে এই পদ্ধতিটি গ্রহণ করতে পারি?
লাইনে

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

@ ঝুগুওয়ে: কিছু মান উত্পন্ন অভ্যন্তরীণ কোডটি ফেরত দেবেন? এর মানে কি বোঝাতে চাচ্ছো?
সৌরভ পাতিল

34

doAnswerএবং thenReturnএকই জিনিস যদি:

  1. আপনি মক ব্যবহার করছেন, স্পাই নয়
  2. আপনি যে পদ্ধতিতে ঝাঁকুনি দিচ্ছেন তা কোনও শূন্য পদ্ধতি নয়, একটি মান ফিরিয়ে দিচ্ছে।

আসুন এই বুক সার্ভিসটিকে উপহাস করুন

public interface BookService {
    String getAuthor();
    void queryBookTitle(BookServiceCallback callback);
}

আপনি getAuthor () ব্যবহার করে শহরের উপর অসম্পূর্ণ নিবন্ধ করতে পারেন doAnswerএবং thenReturn

BookService service = mock(BookService.class);
when(service.getAuthor()).thenReturn("Joshua");
// or..
doAnswer(new Answer() {
    @Override
    public Object answer(InvocationOnMock invocation) throws Throwable {
        return "Joshua";
    }
}).when(service).getAuthor();

মনে রাখবেন যে ব্যবহার করার সময় doAnswer, আপনি কোনও পদ্ধতি পাস করতে পারবেন না when

// Will throw UnfinishedStubbingException
doAnswer(invocation -> "Joshua").when(service.getAuthor());

সুতরাং, আপনি কখন doAnswerপরিবর্তে ব্যবহার করবেন thenReturn? আমি দুটি ব্যবহারের ক্ষেত্রে ভাবতে পারি:

  1. যখন আপনি "স্টাব" শূন্য পদ্ধতি করতে চান।

DoAnswer ব্যবহার করে আপনি পদ্ধতি আহ্বানের উপর কিছু অতিরিক্ত ক্রিয়াকলাপ করতে পারেন। উদাহরণস্বরূপ, ক্যুয়ারবুকটিটলে একটি কলব্যাক ট্রিগার করুন।

BookServiceCallback callback = new BookServiceCallback() {
    @Override
    public void onSuccess(String bookTitle) {
        assertEquals("Effective Java", bookTitle);
    }
};
doAnswer(new Answer() {
    @Override
    public Object answer(InvocationOnMock invocation) throws Throwable {
        BookServiceCallback callback = (BookServiceCallback) invocation.getArguments()[0];
        callback.onSuccess("Effective Java");
        // return null because queryBookTitle is void
        return null;
    }
}).when(service).queryBookTitle(callback);
service.queryBookTitle(callback);
  1. আপনি যখন মকের পরিবর্তে স্পাই ব্যবহার করছেন

স্পাই মকিতোতে কখন-তখন-রিটার্ন ব্যবহার করার সময় আসল পদ্ধতিটি কল করবে এবং তারপরে আপনার উত্তরটি আটকে দেবে। আপনি যদি এই নমুনাটির মতো সত্যিকারের পদ্ধতিটি কল করতে না চান তবে এটি সমস্যার সৃষ্টি করতে পারে:

List list = new LinkedList();
List spy = spy(list);
// Will throw java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
when(spy.get(0)).thenReturn("java");
assertEquals("java", spy.get(0));

DoAnswer ব্যবহার করে আমরা এটিকে নিরাপদে আটকে দিতে পারি।

List list = new LinkedList();
List spy = spy(list);
doAnswer(invocation -> "java").when(spy).get(0);
assertEquals("java", spy.get(0));

প্রকৃতপক্ষে, আপনি যদি পদ্ধতিটি আমন্ত্রণের ভিত্তিতে অতিরিক্ত ক্রিয়া না করতে চান, আপনি কেবল ব্যবহার করতে পারেন doReturn

List list = new LinkedList();
List spy = spy(list);
doReturn("java").when(spy).get(0);
assertEquals("java", spy.get(0));

যদি বিদ্রূপের পদ্ধতিটি বাতিল হয়?
ইগোর ডনিন

1
ইগর, ঠিক সেখানেই ডুঅনসওয়ার () ছবিতে আসে এবং তিনি এটি উপরের উত্তরে hasেকে রেখেছিলেন।
সৌরভ পাতিল

doAnswer(new Answer() { ... return null;}আমি যখন উত্তর গ্রহণের জন্য গ্রহণের জন্য একটি সতর্কতা পেয়েছি "উত্তর একটি কাঁচা টাইপ। জেনেরিক প্রকারের উত্তর <T> পরামিতি করা উচিত" for এটির সমাধানের কোনও উপায় আছে (সতর্কতার বিষয়টি উপেক্ষা করে)?
LazR
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.