মকিটোস আর্গুমেন্টক্যাপ্টোর ব্যবহার করে নির্দিষ্ট ধরণের একটি তালিকা ক্যাপচার করার কোনও উপায় আছে কি? এটি কাজ করে না:
ArgumentCaptor<ArrayList<SomeType>> argument = ArgumentCaptor.forClass(ArrayList.class);
মকিটোস আর্গুমেন্টক্যাপ্টোর ব্যবহার করে নির্দিষ্ট ধরণের একটি তালিকা ক্যাপচার করার কোনও উপায় আছে কি? এটি কাজ করে না:
ArgumentCaptor<ArrayList<SomeType>> argument = ArgumentCaptor.forClass(ArrayList.class);
উত্তর:
নেস্টেড জেনেরিক্স-সমস্যা @ ক্যাপ্টর টিকা দিয়ে এড়ানো যেতে পারে :
public class Test{
@Mock
private Service service;
@Captor
private ArgumentCaptor<ArrayList<SomeType>> captor;
@Before
public void init(){
MockitoAnnotations.initMocks(this);
}
@Test
public void shouldDoStuffWithListValues() {
//...
verify(service).doStuff(captor.capture()));
}
}
MockitoAnnotations.initMocks(this)
না করে @Before
পদ্ধতিতে ব্যবহার করা পছন্দ করি । তবে, +1, টীকাটি নির্দেশ করার জন্য ধন্যবাদ।
হ্যাঁ, এটি সাধারণ জেনেরিক সমস্যা, মকিতো-নির্দিষ্ট নয়।
এর জন্য কোনও শ্রেণীর অবজেক্ট নেই ArrayList<SomeType>
এবং সুতরাং আপনি কোনও প্রয়োজনীয়তার কোনও পদ্ধতিতে নিরাপদে এই জাতীয় বস্তুটি নিরাপদে টাইপ করতে পারবেন না Class<ArrayList<SomeType>>
।
আপনি সঠিক ধরণে বস্তুটি ফেলে দিতে পারেন:
Class<ArrayList<SomeType>> listClass =
(Class<ArrayList<SomeType>>)(Class)ArrayList.class;
ArgumentCaptor<ArrayList<SomeType>> argument = ArgumentCaptor.forClass(listClass);
এটি অনিরাপদ জঞ্জাল সম্পর্কে কিছু সতর্কতা দেবে, এবং অবশ্যই আপনার আরগমেন্টক্যাপ্টর সত্যই ArrayList<SomeType>
এবং এর মধ্যে পার্থক্য করতে পারে নাArrayList<AnotherType>
হয়তো উপাদান পরিদর্শন ছাড়াই।
(অন্য উত্তরে যেমন উল্লেখ করা হয়েছে, যদিও এটি সাধারণ জেনেরিক সমস্যা, তবে @Captor
টীকা সহ ধরণের সুরক্ষা সমস্যার জন্য মকিতো-নির্দিষ্ট সমাধান রয়েছে It এটি এখনও একটি ArrayList<SomeType>
এবং একটি মধ্যে পার্থক্য করতে পারে না ArrayList<OtherType>
))
এছাড়াও কটাক্ষপাত tenshi এর মন্তব্যে। আপনি পাওলো ইবারম্যান থেকে মূল কোডটি এটিতে পরিবর্তন করতে পারেন (অনেক সহজ)
final ArgumentCaptor<List<SomeType>> listCaptor
= ArgumentCaptor.forClass((Class) List.class);
ArgumentCaptor<List<SimeType>> argument = ArgumentCaptor.forClass((Class) List.class);
@SuppressWarnings("unchecked")
আর্গুমেন্ট ক্যাপ্টর সংজ্ঞা লাইনের উপরে টিকাটি ব্যবহার করুন । এছাড়াও, Class
castালাই অনর্থক।
Class
আমার পরীক্ষাগুলিতে কাস্টিং অনর্থক নয়।
আপনি যদি পুরানো জাভা-স্টাইল (নন-টাইপ নিরাপদ জেনেরিক) শব্দার্থবিজ্ঞানের বিষয়ে ভীত না হন তবে এটি কাজ করে এবং যুক্তিসঙ্গতভাবে সহজ:
ArgumentCaptor<List> argument = ArgumentCaptor.forClass(List.class);
verify(subject.method(argument.capture()); // run your code
List<SomeType> list = argument.getValue(); // first captured List, etc.
List<String> mockedList = mock(List.class);
List<String> l = new ArrayList();
l.add("someElement");
mockedList.addAll(l);
ArgumentCaptor<List> argumentCaptor = ArgumentCaptor.forClass(List.class);
verify(mockedList).addAll(argumentCaptor.capture());
List<String> capturedArgument = argumentCaptor.<List<String>>getValue();
assertThat(capturedArgument, hasItem("someElement"));
@ টেনশি এবং @ পাকালিনোর মন্তব্যের ভিত্তিতে (@rogerdpack এর কাছেও কুদো) নীচে, একটি তালিকা আর্গুমেন্ট ক্যাপ্টর তৈরির জন্য একটি সহজ সমাধান যা "চেক করা বা অনিরাপদ অপারেশনগুলি ব্যবহার করে" সতর্কতাটিকে অক্ষম করে :
@SuppressWarnings("unchecked")
final ArgumentCaptor<List<SomeType>> someTypeListArgumentCaptor =
ArgumentCaptor.forClass(List.class);
এখানে সম্পূর্ণ উদাহরণ এবং সংশ্লিষ্ট পাসিং সিআই বিল্ড এবং পরীক্ষা এখানে চালানো ।
আমাদের দলটি আমাদের ইউনিট পরীক্ষাগুলিতে কিছু সময়ের জন্য এটি ব্যবহার করে আসছে এবং এটি আমাদের জন্য সবচেয়ে সহজ সমাধান বলে মনে হচ্ছে।
জুনিটের পূর্ববর্তী সংস্করণের জন্য, আপনি এটি করতে পারেন
Class<Map<String, String>> mapClass = (Class) Map.class;
ArgumentCaptor<Map<String, String>> mapCaptor = ArgumentCaptor.forClass(mapClass);
আমার অ্যান্ড্রয়েড অ্যাপ্লিকেশনটিতে পরীক্ষার ক্রিয়াকলাপ নিয়ে আমার একই সমস্যা ছিল। আমি ব্যবহার করেছি ActivityInstrumentationTestCase2
এবং MockitoAnnotations.initMocks(this);
কাজ করিনি। আমি এই সমস্যাটি যথাযথ ক্ষেত্র সহ অন্য শ্রেণীর সাথে সমাধান করেছি। উদাহরণ স্বরূপ:
class CaptorHolder {
@Captor
ArgumentCaptor<Callback<AuthResponse>> captor;
public CaptorHolder() {
MockitoAnnotations.initMocks(this);
}
}
তারপরে, কার্যকলাপ পরীক্ষা পদ্ধতিতে:
HubstaffService hubstaffService = mock(HubstaffService.class);
fragment.setHubstaffService(hubstaffService);
CaptorHolder captorHolder = new CaptorHolder();
ArgumentCaptor<Callback<AuthResponse>> captor = captorHolder.captor;
onView(withId(R.id.signInBtn))
.perform(click());
verify(hubstaffService).authorize(anyString(), anyString(), captor.capture());
Callback<AuthResponse> callback = captor.getValue();
এই সঠিক সমস্যাটি সম্পর্কে মকিতোর গিটহাবে একটি উন্মুক্ত সমস্যা রয়েছে।
আমি একটি সাধারণ কাজ খুঁজে পেয়েছি যা আপনাকে আপনার পরীক্ষাগুলিতে টীকাগুলি ব্যবহার করতে বাধ্য করে না:
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.MockitoAnnotations;
public final class MockitoCaptorExtensions {
public static <T> ArgumentCaptor<T> captorFor(final CaptorTypeReference<T> argumentTypeReference) {
return new CaptorContainer<T>().captor;
}
public static <T> ArgumentCaptor<T> captorFor(final Class<T> argumentClass) {
return ArgumentCaptor.forClass(argumentClass);
}
public interface CaptorTypeReference<T> {
static <T> CaptorTypeReference<T> genericType() {
return new CaptorTypeReference<T>() {
};
}
default T nullOfGenericType() {
return null;
}
}
private static final class CaptorContainer<T> {
@Captor
private ArgumentCaptor<T> captor;
private CaptorContainer() {
MockitoAnnotations.initMocks(this);
}
}
}
কি হয় এখানে যে আমরা একটি নতুন শ্রেণী তৈরি হয় সঙ্গে@Captor
টীকা এবং তা বন্দিকারী উদ্বুদ্ধ। তারপরে আমরা কেবল বন্দিদশাটি বের করব এবং আমাদের স্থিতিশীল পদ্ধতি থেকে এটি ফিরিয়ে দেব।
আপনার পরীক্ষায় আপনি এটি এর মতো ব্যবহার করতে পারেন:
ArgumentCaptor<Supplier<Set<List<Object>>>> fancyCaptor = captorFor(genericType());
অথবা সিনট্যাক্সের সাথে যা জ্যাকসনের অনুরূপ TypeReference
:
ArgumentCaptor<Supplier<Set<List<Object>>>> fancyCaptor = captorFor(
new CaptorTypeReference<Supplier<Set<List<Object>>>>() {
}
);
এটি কাজ করে, কারণ মকিতোকে আসলে কোনও ধরণের তথ্যের প্রয়োজন হয় না (উদাহরণস্বরূপ সিরিয়ালাইজারগুলির বিপরীতে)।
ArrayList
)। আপনি সর্বদাList
ইন্টারফেস ব্যবহার করতে পারেন , এবং যদি আপনি এই সত্যটি উপস্থাপন করতে চান যে এটিextends
ArgumentCaptor<? extends List<SomeType>>