মকিতো এক পদ্ধতির আর্গুমেন্ট একাধিকবার ক্যাপচার করতে পারে?


446

আমার কাছে এমন একটি পদ্ধতি রয়েছে যা দুবার কল হয়ে যায় এবং আমি দ্বিতীয় পদ্ধতি কলের যুক্তিটি ক্যাপচার করতে চাই।

এখানে আমি চেষ্টা করেছি:

ArgumentCaptor<Foo> firstFooCaptor = ArgumentCaptor.forClass(Foo.class);
ArgumentCaptor<Foo> secondFooCaptor = ArgumentCaptor.forClass(Foo.class);
verify(mockBar).doSomething(firstFooCaptor.capture());
verify(mockBar).doSomething(secondFooCaptor.capture());
// then do some assertions on secondFooCaptor.getValue()

তবে আমি একটি TooManyActualInvocationsব্যতিক্রম পেয়েছি , যেমন মকিতো মনে করে যে এটি doSomethingএকবারই ডাকা উচিত।

দ্বিতীয় কলটির যুক্তিটি আমি কীভাবে যাচাই করতে পারি doSomething?

উত্তর:


784

আমি মনে করি এটি

verify(mockBar, times(2)).doSomething(...)

মকিতো জাভাদোক থেকে নমুনা :

ArgumentCaptor<Person> peopleCaptor = ArgumentCaptor.forClass(Person.class);
verify(mock, times(2)).doSomething(peopleCaptor.capture());

List<Person> capturedPeople = peopleCaptor.getAllValues();
assertEquals("John", capturedPeople.get(0).getName());
assertEquals("Jane", capturedPeople.get(1).getName());

3
আপনি কি এর doSomething()সাথে প্রতিটি পৃথক অনুরোধে পাস হওয়া যুক্তিগুলি ক্যাপচার করতে পারেন ?
ম্যাট বি

36
এটি লক্ষ করা উচিত যে আপনি যদি এইরকম কিছু করেন Person person = new Person("John"); doSomething(person); person.setName("Jane"); doSomething(person);তবে ধরা পড়ার যুক্তি দু'বার একই হবে (কারণ এটি আসলে একই ব্যক্তির আপত্তি), সুতরাং capturedPeople.get(0).getName() == capturedPeople.get(1).getName() == "Jane", আরও দেখুন google.com/forum/#!msg/mockito/ KBRocVedYT0 / 5HtARMl9r2wJ
asmaier

2
এটি দুর্দান্ত, তবে আমি কীভাবে দুটি ভিন্ন টাইপযুক্ত অবজেক্টের অনুরোধ পরীক্ষা করতে পারি? উদাহরণস্বরূপ এক্সিকিউটর সার্ভিস.সাম্বিট (নতুন MyRunableImpl ()); এবং তারপরে এক্সিকিউটর সার্ভিস.সাম্বিট (নতুন মাইঅনথরআনেবলআইপল ())?
লিওন

: এক চাহিদা ক্ষেত্রে @asmaier দ্বারা বর্ণিত হ্যান্ডেল করতে পারেন, আমি এখানে একটি উত্তর পোস্ট stackoverflow.com/a/36574817/1466267
SpaceTrucker

1
লেওনের প্রশ্নের উত্তরের বিষয়ে এখনও যে কেউ ভাবছেন, আপনি সাধারণ বেস ক্লাসটি ব্যবহার করবেন ( Runnable) এবং প্রয়োজন হলে বন্দী যুক্তির উপর আরও নির্দিষ্ট ধরণের চেক করুন।
ম্যাথু

50

মকিতো ২.০ থেকে স্থির পদ্ধতি ব্যবহারেরও সম্ভাবনা রয়েছে ম্যাচার্স.আরজিথ (আর্গুমেন্ট ম্যাচার) । জাভা 8 এর সাহায্যে এটি এখন আরও পরিষ্কার এবং আরও পাঠযোগ্য:

verify(mockBar).doSth(argThat((arg) -> arg.getSurname().equals("OneSurname")));
verify(mockBar).doSth(argThat((arg) -> arg.getSurname().equals("AnotherSurname")));

যদি আপনি নীচের জাভা সংস্করণে আবদ্ধ হন তবে এটিও খারাপ-খারাপ নয়:

verify(mockBar).doSth(argThat(new ArgumentMatcher<Employee>() {
        @Override
        public boolean matches(Object emp) {
            return ((Employee) emp).getSurname().equals("SomeSurname");
        }
    }));

অবশ্যই তাদের মধ্যে কেউই কলগুলির ক্রম যাচাই করতে পারে না - যার জন্য আপনার ইনঅর্ডার ব্যবহার করা উচিত :

InOrder inOrder = inOrder(mockBar);

inOrder.verify(mockBar).doSth(argThat((arg) -> arg.getSurname().equals("FirstSurname")));
inOrder.verify(mockBar).doSth(argThat((arg) -> arg.getSurname().equals("SecondSurname")));

দয়া করে কটাক্ষপাত করা mockito-java8 যা যেমন কল করার জন্য সম্ভব করে তোলে প্রকল্প:

verify(mockBar).doSth(assertArg(arg -> assertThat(arg.getSurname()).isEqualTo("Surname")));

2
এটি একটি দুর্দান্ত কৌশল। যদিও আমি বর্তমানে কিছু বরং ক্রিপ্টিক আউটপুট পাচ্ছি: "চেয়েছিলেন তবে অনুরোধ করা হয়নি: / n mockAppender.append (<সূচকের পরিচালক মজাদার $ 5 9/1 3 1 9 5 1 0 1 6>);" - আরগ আছে a CharSequence। "আকাঙ্ক্ষিত" টিপটি সঠিকভাবে ছাপানোর জন্য প্রতিবেদনটি পাওয়ার কোনও উপায় সম্পর্কে আপনি কি জানেন?
মাইকে রডেন্ট

@ মিকেরোডেন্ট আপনি অরগমেন্টমেচার <টি> প্রয়োগ করে এমন শ্রেণি তৈরির আরও ভার্জিক রুটে গেলে ক্রিপ্টিক আউটপুট ঠিক করা যায়। আপনার প্রয়োগে টসস্ট্রিং পদ্ধতিকে ওভাররাইড করা মকিতো পরীক্ষার আউটপুটে আপনার যে কোনও বার্তা চাইবে provide
নোহ সলোমন

25

আপনি যদি সমস্ত কলগুলিতে বৈধতা দিতে না চান তবে doSomething()কেবল সর্বশেষ একটি, আপনি কেবল ব্যবহার করতে পারেন ArgumentCaptor.getValue()মকিতো জাভাদোক অনুসারে :

যদি পদ্ধতিটি একাধিকবার বলা হয় তবে এটি সর্বশেষ গৃহীত মানটি প্রদান করে

সুতরাং এটি কাজ করবে (ধরে Fooনেওয়া একটি পদ্ধতি আছে getName()):

ArgumentCaptor<Foo> fooCaptor = ArgumentCaptor.forClass(Foo.class);
verify(mockBar, times(2)).doSomething(fooCaptor.capture());
//getValue() contains value set in second call to doSomething()
assertEquals("2nd one", fooCaptor.getValue().getName());

উভয় মান ক্যাপচার কোন উপায় আছে?
হারস

9

আপনি @ ক্যাপ্টর টিকাশিত আর্গুমেন্টক্যাপ্টর ব্যবহার করতে পারেন। উদাহরণ স্বরূপ:

@Mock
List<String> mockedList;

@Captor
ArgumentCaptor<String> argCaptor;

@BeforeTest
public void init() {
    //Initialize objects annotated with @Mock, @Captor and @Spy.
    MockitoAnnotations.initMocks(this);
}

@Test
public void shouldCallAddMethodTwice() {
    mockedList.add("one");
    mockedList.add("two");
    Mockito.verify(mockedList, times(2)).add(argCaptor.capture());

    assertEquals("one", argCaptor.getAllValues().get(0));
    assertEquals("two", argCaptor.getAllValues().get(1));
}

6

জাভা 8 এর ল্যাম্বডাস সহ, একটি সুবিধাজনক উপায় ব্যবহার করা

org.mockito.invocation.InvocationOnMock

when(client.deleteByQuery(anyString(), anyString())).then(invocationOnMock -> {
    assertEquals("myCollection", invocationOnMock.getArgument(0));
    assertThat(invocationOnMock.getArgument(1), Matchers.startsWith("id:"));
}

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

0

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

import static org.mockito.Mockito.*;

যাচাই () পদ্ধতিতে আপনি পরীক্ষায় মৃত্যুদণ্ড কার্যকর করার আশ্বাস দিতে আরগমেন্টক্যাপ্টর এবং আর্গুমেন্টক্যাপ্টরকে আর্গুমেন্টগুলি মূল্যায়নের জন্য পাস করতে পারেন:

ArgumentCaptor<MyExampleClass> argument = ArgumentCaptor.forClass(MyExampleClass.class);
verify(yourmock, atleast(2)).myMethod(argument.capture());

List<MyExampleClass> passedArguments = argument.getAllValues();

for (MyExampleClass data : passedArguments){
    //assertSometing ...
    System.out.println(data.getFoo());
}

আপনার পরীক্ষার সময় পাস হওয়া সমস্ত আর্গুমেন্টের তালিকাটি আর্গুমেন্ট.জেটএলভ্যালু () পদ্ধতির মাধ্যমে অ্যাক্সেসযোগ্য।

আরও হেরফের / চেকিং বা আপনি যা করতে চান তার জন্য একক (সর্বশেষ বলা) আর্গুমেন্টের মানটি আর্গুমেন্ট.জেটভ্যালু () এর মাধ্যমে অ্যাক্সেসযোগ্য।

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