মকিটো দিয়ে অবজেক্টের বৈশিষ্ট্য মানটি যাচাই করুন


264

আমার একটি পদ্ধতি কল রয়েছে যা আমি মকিতো দিয়ে উপহাস করতে চাই। শুরু করার জন্য আমি কোনও অবজেক্টের একটি উদাহরণ তৈরি করেছি এবং ইনজেকশন দিয়েছি যার ভিত্তিতে পদ্ধতিটি কল হবে। আমার উদ্দেশ্যটি হ'ল মেথড কলের মধ্যে কোনও একটিকে যাচাই করা।

মকিটো এমন কোনও উপায় আছে যেখানে মকিতো আপনাকে অবজেক্টটি দৃsert়তা বা যাচাই করার অনুমতি দেয় এবং মক পদ্ধতিটি যখন ডাকা হয় তখন এর বৈশিষ্ট্যগুলি থাকে?

উদাহরণ

Mockito.verify(mockedObject)
       .someMethodOnMockedObject(
              Mockito.<SomeObjectAsArgument>anyObject())

পরিবর্তে anyObject()আমি পরীক্ষা করতে চাই যে আর্গুমেন্ট অবজেক্টে কিছু নির্দিষ্ট ক্ষেত্র রয়েছে

Mockito.verify(mockedObject)
       .someMethodOnMockedObject(
              Mockito.<SomeObjectAsArgument>**compareWithThisObject()**)

এই ক্ষেত্রে মকিতো ব্যবহারের বিকল্প হিসাবে, আপনি একটি কাস্টম স্টাব তৈরির বিষয়টি বিবেচনা করতে পারেন যা মকডঅবজেক্টের ক্লাসকে প্রসারিত করে এবং পরবর্তীকালের তুলনার জন্য অবজেক্টটি সংরক্ষণ করতে কিছু মেথডঅনমকডবজেক্টকে ওভাররাইড করে।
গোনেন আই

উত্তর:


539

মকিতোতে যুক্ত হওয়া নতুন বৈশিষ্ট্য এটি আরও সহজ করে তোলে,

ArgumentCaptor<Person> argument = ArgumentCaptor.forClass(Person.class);
verify(mock).doSomething(argument.capture());
assertEquals("John", argument.getValue().getName());

মকিটো ডকুমেন্টেশন একবার দেখুন


যদি একাধিক প্যারামিটার থাকে এবং কেবলমাত্র একক প্যারামের ক্যাপচারটি পছন্দ হয় তবে বাকী আর্গুমেন্টগুলি মোড়ানোর জন্য অন্যান্য আরগমেন্টমাচারগুলি ব্যবহার করুন:

verify(mock).doSomething(eq(someValue), eq(someOtherValue), argument.capture());
assertEquals("John", argument.getValue().getName());

1
যদি আপনার পদ্ধতিতে একাধিক যুক্তি থাকে তবে আপনাকে অবশ্যই অন্য সমস্ত যুক্তির জন্য ম্যাচার্স ব্যবহার করতে হবে। akcasoy.wordpress.com/tag/argumentcaptor
রোবসনরোসা

1
একাধিক যুক্তি থাকলে কী হবে? আপনি আগ্রহী ঠিক কীভাবে নির্দিষ্ট করবেন?
ইগোরগানাপলস্কি

2
@ ইগোরগানাপলস্কি ডুসের জন্য দ্বিতীয় স্ট্রিং প্যারামিটার ধরে নিয়ে যা কিছু করা দরকার: যাচাই করুন (মক) .ডোমোথিং (আর্গুমেন্ট।
গ্রিন টার্টল

সমস্ত আর্গুমেন্টের জন্য ম্যাথার ব্যবহার করার প্রয়োজনটি পুরোপুরি স্ট্যান্ডার্ড অল-বা-না ম্যাচের ব্যবহারের ক্ষেত্রে নির্দিষ্ট per
চার্নি কায়ে

54

আমি মনে করি একটি আর্গুমেন্ট অবজেক্ট যাচাইয়ের সবচেয়ে সহজ উপায় হ'ল refEqপদ্ধতিটি ব্যবহার করা :

Mockito.verify(mockedObject).someMethodOnMockedObject(Matchers.refEq(objectToCompareWith));

বস্তুটি বাস্তবায়ন না করলেও এটি ব্যবহার করা যেতে পারে equals(), কারণ প্রতিবিম্ব ব্যবহার করা হয়। আপনি যদি কিছু ক্ষেত্রের তুলনা করতে না চান তবে তাদের নাম যুক্তি হিসাবে যুক্ত করুন refEq


1
এটি একটি খুব মার্জিত উপায় তবে দুর্ভাগ্যক্রমে org.mockito. ম্যাচার্স এখন
অবহেলিত

5
@ আইহেবিহেব এটি আর্গুমেন্ট ম্যাচার্সে স্থানান্তরিত করেছেন
মাইকেল

48

আরও একটি সম্ভাবনা, যদি আপনি ব্যবহার করতে না চান ArgumentCaptor(উদাহরণস্বরূপ, কারণ আপনি স্টাবিংও ব্যবহার করছেন), হ'ল ম্যাকিতোর সাথে মিশ্রিতভাবে হামক্রস্ট ম্যাচার্স ব্যবহার করা।

import org.mockito.Mockito
import org.hamcrest.Matchers
...

Mockito.verify(mockedObject).someMethodOnMockedObject(MockitoHamcrest.argThat(
    Matchers.<SomeObjectAsArgument>hasProperty("propertyName", desiredValue)));

2
সিডিনোট: Matchersপ্যাকেজটি সঠিক কিনা তা নিশ্চিত করুন , org.mockito.Matchersক্লাসের সাথে একই লাইনের কোড লেখার ফলে একটি বিভ্রান্তিকর ব্যতিক্রম ছোঁড়ে যা উল্লেখ করে যে মক ফাংশনের প্যারামিটারটি কেবল মেলে না।
বুয়ার 20'18

1
দয়া করে মনে রাখবেন যে আধুনিক মকিতো সংস্করণগুলিতে এটি রয়েছে MockitoHamcrest.argThat()এবং তা নয়Mockito.argThat()
রোমান পুচকোভস্কি

17

এটি আইরাসেনথিলের উত্তরের ভিত্তিতে তবে টিকা ( ক্যাপ্টর ) এর সাথে উত্তর । আমার মতে এটির কিছু সুবিধা রয়েছে:

  • এটি খাটো
  • এটি পড়া সহজ
  • এটি সতর্কতা ছাড়াই জেনারিকগুলি পরিচালনা করতে পারে

উদাহরণ:

@RunWith(MockitoJUnitRunner.class)
public class SomeTest{

    @Captor
    private ArgumentCaptor<List<SomeType>> captor;

    //...

    @Test 
    public void shouldTestArgsVals() {
        //...
        verify(mockedObject).someMethodOnMockedObject(captor.capture());

        assertThat(captor.getValue().getXXX(), is("expected"));
    }
}

এটি কেবলমাত্র প্যারামে একক যুক্তির জন্য কাজ করবে।
ইগোরগানাপলস্কি

আপনি একাধিক যুক্তির জন্য একজন বন্দী ব্যবহার করতে পারেন। আপনি যদি একাধিক যুক্তি ক্যাপচার করেন তবে এর সাথে সমস্ত ফলাফলের তালিকা তৈরি করতে পারেন captor.getAllValues()captor.getValue()উত্তরে যে পদ্ধতিটি ব্যবহৃত হয় তা শেষ ফলাফল সরবরাহ করে।
ওয়ালারি স্ট্রাচ

11

আপনি যদি জাভা 8 ব্যবহার করে থাকেন তবে আপনি ম্যাচের জন্য ল্যাম্বডা এক্সপ্রেশন ব্যবহার করতে পারেন।

import java.util.Optional;
import java.util.function.Predicate;

import org.hamcrest.BaseMatcher;
import org.hamcrest.Description;

public class LambdaMatcher<T> extends BaseMatcher<T>
{
    private final Predicate<T> matcher;
    private final Optional<String> description;

    public LambdaMatcher(Predicate<T> matcher)
    {
        this(matcher, null);
    }

    public LambdaMatcher(Predicate<T> matcher, String description)
    {
        this.matcher = matcher;
        this.description = Optional.ofNullable(description);
    }

    @SuppressWarnings("unchecked")
    @Override
    public boolean matches(Object argument)
    {
        return matcher.test((T) argument);
    }

    @Override
    public void describeTo(Description description)
    {
        this.description.ifPresent(description::appendText);
    }
}

উদাহরণ কল

@Test
public void canFindEmployee()
{
    Employee employee = new Employee("John");
    company.addEmployee(employee);

    verify(mockedDal).registerEmployee(argThat(new LambdaMatcher<>(e -> e.getName()
                                                                         .equals(employee.getName()))));
}

আরও তথ্য: http://source.coveo.com/2014/10/01/java8-mockito/


5

উপরের সমাধানগুলি সত্যিই আমার ক্ষেত্রে কার্যকর হয়নি। পদ্ধতিটি বেশ কয়েকবার কল করা হয়েছিল বলে আমি আরগমেন্টক্যাপ্টরটি ব্যবহার করতে পারি নি এবং আমার প্রতিটিটি বৈধ করে তোলা দরকার। "আরগথ্যাট" সহ একটি সাধারণ ম্যাচার সহজেই কৌশলটি সম্পাদন করেছিলেন।

কাস্টম ম্যাচার

// custom matcher
private class PolygonMatcher extends ArgumentMatcher<PolygonOptions> {
    private int fillColor;
    public PolygonMatcher(int fillColor) {
        this.fillColor = fillColor;
    }

    @Override
    public boolean matches(Object argument) {
        if (!(argument instanceof PolygonOptions)) return false;
        PolygonOptions arg = (PolygonOptions)argument;
        return Color.red(arg.getFillColor()) == Color.red(fillColor)
                && Color.green(arg.getFillColor()) == Color.green(fillColor)
                && Color.blue(arg.getFillColor()) == Color.blue(fillColor);
    }
}

টেস্ট রানার

// do setup work setup
// 3 light green polygons
int green = getContext().getResources().getColor(R.color.dmb_rx_bucket1);
verify(map, times(3)).addPolygon(argThat(new PolygonMatcher(green)));

// 1 medium yellow polygons
int yellow = getContext().getResources().getColor(R.color.dmb_rx_bucket4);
    verify(map, times(1)).addPolygon(argThat(new PolygonMatcher(yellow)));

// 3 red polygons
int orange = getContext().getResources().getColor(R.color.dmb_rx_bucket5);
verify(map, times(3)).addPolygon(argThat(new PolygonMatcher(orange)));

// 2 red polygons
int red = getContext().getResources().getColor(R.color.dmb_rx_bucket7);
verify(map, times(2)).addPolygon(argThat(new PolygonMatcher(red)));

3

এবং কোল্টিন থেকে খুব সুন্দর এবং পরিষ্কার সমাধান com.nhaarman.mockito_kotlin

verify(mock).execute(argThat {
    this.param = expected
})

1

আপনি নিম্নলিখিত উল্লেখ করতে পারেন:

Mockito.verify(mockedObject).someMethodOnMockedObject(eq(desiredObject))

এটি যাচাই-বাজেক্টের পদ্ধতিটিকে পছন্দসই অবজেক্টের সাথে প্যারামিটার হিসাবে ডাকা হয় কিনা তা যাচাই করবে।


1

এটি করার আরেকটি সহজ উপায়:

import org.mockito.BDDMockito;    
import static org.mockito.Matchers.argThat;
import org.mockito.ArgumentMatcher;

BDDMockito.verify(mockedObject)
        .someMethodOnMockedObject(argThat(new ArgumentMatcher<TypeOfMethodArg>() {

            @Override
            public boolean matches(Object argument) {
                final TypeOfMethodArg castedArg = (TypeOfMethodArg) argument;

                // Make your verifications and return a boolean to say if it matches or not
                boolean isArgMarching = true;

                return isArgMarching;
            }
        }));

0

রেফেকের জাভাডোক উল্লেখ করেছে যে সমতা পরীক্ষাটি অগভীর! আপনি নীচের লিঙ্কে আরও বিশদ জানতে পারেন:

[ Https://static.javadoc.io/org.mockito/mockito-core/2.2.29/org/mockito/ArgumentMatchers.html#refEq(T,%20java.lang.String...)][1]

"অগভীর সমতা" ইস্যুটি নিয়ন্ত্রণ করা যায় না যখন আপনি অন্যান্য ক্লাস ব্যবহার করেন যা .equals () পদ্ধতি প্রয়োগ করে না, "DefaultMongoTypeMapper" শ্রেণি একটি উদাহরণ যেখানে .aquals () পদ্ধতি প্রয়োগ করা হয়নি।

org.springframework.beans.factory.support এমন একটি পদ্ধতি উপলব্ধ করে যা বস্তুর উদাহরণ তৈরি করার পরিবর্তে শিম সংজ্ঞা তৈরি করতে পারে এবং তুলনা ব্যর্থতা থেকে মুক্তি পেতে এটি ব্যবহার করা যেতে পারে।

 genericBeanDefinition(DefaultMongoTypeMapper.class)
                        .setScope(SCOPE_SINGLETON)
                        .setAutowireMode(AUTOWIRE_CONSTRUCTOR)
                        .setLazyInit(false)
                        .addConstructorArgValue(null)
                        .getBeanDefinition()

** "শিমের সংজ্ঞাটি কেবল শিমের একটি বিবরণ, বিনের নিজেই নয়। একটি তৈরি করা উচিত "

আপনার উদাহরণে, আপনি এর মতো কিছু করতে পারেন

Mockito.verify(mockedObject)
       .doSoething(genericBeanDefinition(YourClass.class).setA("a")
       .getBeanDefinition());

0

একটি নতুন ম্যাচার বাস্তবায়ন শ্রেণি তৈরি না করে এবং ল্যাম্বডা এক্সপ্রেশনটি ব্যবহার না করে একটি সরলিকৃত সমাধান:

        verify(mockObject).someMockMethod(argThat((SomeArgument arg) -> arg.fieldToMatch.equals(expectedFieldValue));
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.