কীভাবে মকিতোতে ভ্যারাগগুলি সঠিকভাবে মেলে


152

আমি মকিতো ব্যবহার করে ভার্গ পরামিতিগুলির সাথে কোনও পদ্ধতি উপহাস করার চেষ্টা করেছি:

interface A {
  B b(int x, int y, C... c);
}

A a = mock(A.class);
B b = mock(B.class);

when(a.b(anyInt(), anyInt(), any(C[].class))).thenReturn(b);
assertEquals(b, a.b(1, 2));

এটি কাজ করে না, তবে আমি পরিবর্তে এটি করলে:

when(a.b(anyInt(), anyInt())).thenReturn(b);
assertEquals(b, a.b(1, 2));

এটি কাজ করে, তবুও পদ্ধতিটি স্ট্যাব করার সময় আমি ভ্যারারগ্স যুক্তিটি পুরোপুরি বাদ দিয়েছি।

কোন সংকেত সনাক্ত করুন?


সর্বশেষ উদাহরণটি যে কাজ করে তা বরং তুচ্ছ কারণ এটি শূন্য ভারার্গ্স পরামিতিগুলি পেরিয়ে যাওয়ার সাথে মেলে।
topchef

উত্তর:


235

মকিতো 1.8.1 কোনও ভারার্গ () ম্যাচারটি চালু করেছে :

when(a.b(anyInt(), anyInt(), Matchers.<String>anyVararg())).thenReturn(b);

এছাড়াও এর জন্য ইতিহাস দেখুন: https://code.google.com/archive/p/mockito/issues/62

অবমূল্যায়নের পরে নতুন সিনট্যাক্স সম্পাদনা করুন :

when(a.b(anyInt(), anyInt(), ArgumentMatchers.<String>any())).thenReturn(b);

26
anyVararg()এটির রিটার্ন টাইপ হিসাবে অবজেক্ট রয়েছে। এটিকে কোনও ভার আরগ প্রকারের (যেমন স্ট্রিং ..., পূর্ণসংখ্যা ... ইত্যাদি) সাথে সামঞ্জস্যপূর্ণ করার জন্য একটি স্পষ্টত castালাই করুন। উদাহরণস্বরূপ, আপনার যদি থাকে তবে আপনি doSomething(Integer number, String ... args)মক / স্টাব কোডটি এর মতো কিছু দিয়ে করতে পারেন when(mock).doSomething(eq(1), (String) anyVarargs())। এটি সংকলনের ত্রুটির যত্ন নেওয়া উচিত।
সাইকো পাঞ্চ

15
তথ্যের জন্য যে কোনও ভারার্গ এখন অবচয় করা হয়েছে: "@ ২.১.০ হিসাবে প্রকাশিত যেকোন () ব্যবহার করুন"
অ্যালেক্সব্যাট

5
Matchersorg.hamcrest.Matchersশ্রেণীর সাথে নামের সংঘর্ষ এড়ানোর জন্য এখন অবহেলিত এবং সম্ভবত মকিতো v3.0 এ মুছে ফেলা হবে। ArgumentMatchersপরিবর্তে ব্যবহার করুন।
জনিড

31

কিছুটা অননুমোদিত বৈশিষ্ট্য: আপনি যদি এমন একটি কাস্টম ম্যাচার বিকাশ করতে চান যা ভ্যারআর্গ যুক্তিগুলির সাথে মেলে তবে এটির org.mockito.internal.matchers.VarargMatcherসঠিকভাবে কাজ করার জন্য এটির প্রয়োগ করা দরকার । এটি একটি খালি মার্কার ইন্টারফেস, যা ব্যতিরেকে আপনার ম্যাচার ব্যবহার করে ভারাজগুলির সাথে কোনও পদ্ধতি চাওয়ার সময় মকিতো আর্গুমেন্টগুলি সঠিকভাবে তুলনা করবে না।

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

class MyVarargMatcher extends ArgumentMatcher<C[]> implements VarargMatcher {
    @Override public boolean matches(Object varargArgument) {
        return /* does it match? */ true;
    }
}

when(a.b(anyInt(), anyInt(), argThat(new MyVarargMatcher()))).thenReturn(b);

7

এখানে এলি লেভিনের উত্তরের উপর ভিত্তি করে তৈরি করা আরও সাধারণ সমাধান:

import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.mockito.ArgumentMatcher;
import org.mockito.internal.matchers.VarargMatcher;

import static org.mockito.Matchers.argThat;

public class VarArgMatcher<T> extends ArgumentMatcher<T[]> implements VarargMatcher {

    public static <T> T[] varArgThat(Matcher<T[]> hamcrestMatcher) {
        argThat(new VarArgMatcher(hamcrestMatcher));
        return null;
    }

    private final Matcher<T[]> hamcrestMatcher;

    private VarArgMatcher(Matcher<T[]> hamcrestMatcher) {
        this.hamcrestMatcher = hamcrestMatcher;
    }

    @Override
    public boolean matches(Object o) {
        return hamcrestMatcher.matches(o);
    }

    @Override
    public void describeTo(Description description) {
        description.appendText("has varargs: ").appendDescriptionOf(hamcrestMatcher);
    }

}

তারপরে আপনি এটি হ্যামক্রাস্টের অ্যারে ম্যাথারগুলির সাথে এটি ব্যবহার করতে পারেন:

verify(a).b(VarArgMatcher.varArgThat(
            org.hamcrest.collection.IsArrayContaining.hasItemInArray("Test")));

(স্পষ্টতই স্থির আমদানি এটিকে আরও বেশি পাঠযোগ্য able


খুশী হলাম। এটি মকিতো আইএমওতে তৈরি করা উচিত।
ব্রায়ান্ট

আমি হেমক্রেস্টের বিরুদ্ধে এই জাতীয় কিছু যুক্ত করার জন্য একটি সমস্যা দায়ের করেছি। Github.com/mockito/mockito/issues/356
চিহ্নিত করুন

এটি কি মকিতো 1 এর জন্য? 2.10 এর বিপরীতে সংকলনের চেষ্টা করার সময় আমি বিভিন্ন সংকলন ত্রুটি পেয়েছি।
ফ্রান্স

@ ফ্রান্স দেখে মনে হচ্ছে 2 টি রিলিজ এখনও বিটাতে ছিল যখন আমি এই উত্তরটি লিখেছিলাম, সুতরাং হ্যাঁ এটি সম্ভবত মকিতো ভি 1.10.19 বা এর আশেপাশে লেখা হয়েছিল। ( github.com/mockito/mockito/relayss ) এটি সম্ভবত আপডেটযোগ্য ... :
পিটার ওয়েস্টম্যাকট

3

আমি পিটার ওয়েস্টম্যাকটের উত্তরে কোডটি ব্যবহার করছি তবে মকিতো ২.২.১৫ এর সাথে আপনি এখন নিম্নলিখিতটি করতে পারেন:

verify(a).method(100L, arg1, arg2, arg3)

যেখানে arg1, arg2, arg3varargs হয়


1

টপচেফের উত্তরে বিল্ডিং,

২.০.৩১-বিটার জন্য আমাকে ম্যাচার্স.নাই ভারার্গের পরিবর্তে মকিতো.অ্যানি ভারার্গ ব্যবহার করতে হয়েছিল:

when(a.b(anyInt(), anyInt(), Mockito.<String>anyVararg())).thenReturn(b);

3
তথ্যের জন্য যে কোনও ভারার্গ এখন অবচয় করা হয়েছে: "@ ২.১.০ হিসাবে প্রকাশিত যেকোন () ব্যবহার করুন"
অ্যালেক্সব্যাট

0

আমার ক্ষেত্রে যে পদ্ধতির আমি তার যুক্তি ধরতে চাইছি তার স্বাক্ষরটি হ'ল:

    public byte[] write(byte ... data) throws IOException;

এই ক্ষেত্রে আপনার স্পষ্টভাবে অ্যারে বাইট করা উচিত :

       when(spi.write((byte[])anyVararg())).thenReturn(someValue);

আমি মকিতো সংস্করণ ব্যবহার করছি 1.10.19


0

আপনি যুক্তিগুলি লুপ করতে পারেন:

Object[] args = invocation.getArguments(); 
for( int argNo = 0; argNo < args.length; ++argNo) { 
    // ... do something with args[argNo] 
}

উদাহরণস্বরূপ, তাদের ধরণগুলি পরীক্ষা করে যথাযথভাবে কাস্ট করুন, একটি তালিকায় বা যা কিছু যোগ করুন।


0

@ টপচেফ থেকে উত্তরটি মানিয়ে নেওয়া,

Mockito.when(a.b(Mockito.anyInt(), Mockito.anyInt(), Mockito.any())).thenReturn(b);

মকিতো ২.২৩.৪ এর জাভা ডক্স অনুসারে, মকিতো.নেই () "নাল এবং ভারার্গস সহ যেকোন কিছুতে মেলে।"


0

আপনি একটি আর্গুমেন্টক্যাপ্টর ক্যাপচারটি পাস করে এবং এরপরে "getAllValues" ব্যবহার করে একটি তালিকা হিসাবে ভ্যারাগগুলি পুনরুদ্ধার করে এটি সম্পাদন করতে পারেন, দেখুন: https://stackoverflow.com/a/55621731/11342928

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