سؤال

كيف تسخر من الطرق بنوع العودة الفراغ؟

لقد قمت بتطبيق نمط مراقب ولكن لا يمكنني السخرية من ذلك مع Mockito لأنني لا أعرف كيف.

وحاولت العثور على مثال على الإنترنت ، لكنني لم تنجح.

يبدو صفي هكذا:

public class World {

    List<Listener> listeners;

    void addListener(Listener item) {
        listeners.add(item);
    }

    void doAction(Action goal,Object obj) {
        setState("i received");
        goal.doAction(obj);
        setState("i finished");
    }

    private string state;
    //setter getter state
} 

public class WorldTest implements Listener {

    @Test public void word{
    World  w= mock(World.class);
    w.addListener(this);
    ...
    ...

    }
}

interface Listener {
    void doAction();
}

لا يتم تشغيل النظام مع وهمية. = (أريد أن أظهر حالة النظام المذكورة أعلاه. والتأكيد وفقًا لهم.

هل كانت مفيدة؟

المحلول 4

حل ما يسمى بالمشكلة هو استخدام أ spy mockito.spy (...) بدل من mock mockito.mock (..).

يمكّننا Spy من السخرية الجزئية. Mockito جيد في هذا الأمر. نظرًا لأن لديك فصلًا غير مكتمل ، وبهذه الطريقة تسخر من بعض المكان المطلوب في هذه الفئة.

نصائح أخرى

ألق نظرة على Mockito مستندات API. كما يذكر المستند المرتبط (النقطة رقم 12) يمكنك استخدام أي من doThrow(),doAnswer(),doNothing(),doReturn() عائلة الأساليب من إطار Mockito لسخر أساليب الفراغ.

علي سبيل المثال،

Mockito.doThrow(new Exception()).when(instance).methodName();

أو إذا كنت ترغب في الجمع بينه وبين سلوك المتابعة ،

Mockito.doThrow(new Exception()).doNothing().when(instance).methodName();

على افتراض أنك تبحث في السخرية من Setter setState(String s) في عالم الفصل أدناه ، يستخدم الكود doAnswer طريقة للسخرية setState.

World  mockWorld = mock(World.class); 
doAnswer(new Answer<Void>() {
    public Void answer(InvocationOnMock invocation) {
      Object[] args = invocation.getArguments();
      System.out.println("called with arguments: " + Arrays.toString(args));
      return null;
    }
}).when(mockWorld).setState(anyString());

أعتقد أنني وجدت إجابة أبسط على هذا السؤال ، لاستدعاء الطريقة الحقيقية لطريقة واحدة فقط (حتى لو كانت لها عودة باطلة) يمكنك القيام بذلك:

Mockito.doCallRealMethod().when(<objectInstance>).<method>();
<objectInstance>.<method>();

أو يمكنك استدعاء الطريقة الحقيقية لجميع طرق ذلك الفصل ، والقيام بذلك:

<Object> <objectInstance> = mock(<Object>.class, Mockito.CALLS_REAL_METHODS);

إضافة إلى ما قاله Sateesh ، عندما تريد فقط السخرية من طريقة الفراغ من أجل منع الاختبار من الاتصال به ، يمكنك استخدام أ Spy من هنا:

World world = new World();
World spy = Mockito.spy(world);
Mockito.doNothing().when(spy).methodToMock();

عندما تريد إجراء الاختبار الخاص بك ، تأكد من الاتصال بالطريقة في الاختبار على spy الكائن وليس على world هدف. علي سبيل المثال:

assertEquals(0,spy.methodToTestThatShouldReturnZero());

بادئ ذي بدء: يجب عليك دائمًا استيراد Mockito ثابت ، وبهذه الطريقة سيكون الكود أكثر قابلية للقراءة (وبديهية):

import static org.mockito.Mockito.*;

من أجل السخرية الجزئية والاحتفاظ بالوظائف الأصلية على الباقي ، يقدم Mockito "Spy".

يمكنك استخدامه على النحو التالي:

private World world = spy(World.class);

للقضاء على طريقة من التنفيذ ، يمكنك استخدام شيء مثل هذا:

doNothing().when(someObject).someMethod(anyObject());

لإعطاء بعض السلوك المخصص لأسلوب استخدامه "عندما" مع "ThenReturn":

doReturn("something").when(this.world).someMethod(anyObject());

لمزيد من الأمثلة ، يرجى العثور على عينات mockito في المستند.

كيفية السخرية من طرق الفراغ مع Mockito - هناك خياران:

  1. doAnswer - إذا كنا نريد طريقة الفراغ السخرية لدينا لفعل شيء (سخر من السلوك على الرغم من كونه باطلاً).
  2. doThrow - ثم هنالك Mockito.doThrow() إذا كنت ترغب في رمي استثناء من طريقة الفراغ السخرية.

فيما يلي مثال على كيفية استخدامه (ليس حجمًا مثاليًا ولكن أراد فقط توضيح الاستخدام الأساسي).

@Test
public void testUpdate() {

    doAnswer(new Answer<Void>() {

        @Override
        public Void answer(InvocationOnMock invocation) throws Throwable {
            Object[] arguments = invocation.getArguments();
            if (arguments != null && arguments.length > 1 && arguments[0] != null && arguments[1] != null) {

                Customer customer = (Customer) arguments[0];
                String email = (String) arguments[1];
                customer.setEmail(email);

            }
            return null;
        }
    }).when(daoMock).updateEmail(any(Customer.class), any(String.class));

    // calling the method under test
    Customer customer = service.changeEmail("old@test.com", "new@test.com");

    //some asserts
    assertThat(customer, is(notNullValue()));
    assertThat(customer.getEmail(), is(equalTo("new@test.com")));

}

@Test(expected = RuntimeException.class)
public void testUpdate_throwsException() {

    doThrow(RuntimeException.class).when(daoMock).updateEmail(any(Customer.class), any(String.class));

    // calling the method under test
    Customer customer = service.changeEmail("old@test.com", "new@test.com");

}
}

يمكنك العثور على مزيد من التفاصيل حول كيفية وهمية و اختبار فارغ طرق مع Mockito في رسالتي كيفية السخرية مع Mockito (دليل شامل مع أمثلة)

إضافة إجابة أخرى على المجموعة (لا يقصد التورية) ...

تحتاج إلى استدعاء طريقة DoAnswer إذا كنت لا تستطيع لا تريد استخدام Spy's. ومع ذلك ، لا تحتاج بالضرورة إلى لفها إجابه. هناك العديد من التطبيقات الافتراضية. والجدير بالذكر ، CallsRealMethods.

في الممارسة العملية ، يبدو شيئًا كهذا:

doAnswer(new CallsRealMethods()).when(mock)
        .voidMethod(any(SomeParamClass.class));

أو:

doAnswer(Answers.CALLS_REAL_METHODS.get()).when(mock)
        .voidMethod(any(SomeParamClass.class));

في Java 8 ، يمكن جعل هذا أكثر نظافة ، على افتراض أن لديك استيراد ثابت org.mockito.Mockito.doAnswer:

doAnswer(i -> {
  // Do stuff with i.getArguments() here
  return null;
}).when(*mock*).*method*(*methodArguments*);

ال return null; من المهم وبدون ذلك ، سيفشل الترجمة مع بعض الأخطاء الغامضة إلى حد ما لأنها لن تكون قادرة على العثور على تجاوز مناسب له doAnswer.

على سبيل المثال ExecutorService هذا ينفذ على الفور Runnable مرت ل execute() يمكن تنفيذها باستخدام:

doAnswer(i -> {
  ((Runnable) i.getArguments()[0]).run();
  return null;
}).when(executor).execute(any());

أعتقد أن مشاكلك بسبب بنية الاختبار. لقد وجدت صعوبة في مزج السخرية مع الطريقة التقليدية لتنفيذ الواجهات في فئة الاختبار (كما فعلت هنا).

إذا قمت بتنفيذ المستمع كخريطة ، فيمكنك التحقق من التفاعل.

Listener listener = mock(Listener.class);
w.addListener(listener);
world.doAction(..);
verify(listener).doAction();

هذا يجب أن يرضيك أن "العالم" يفعل الشيء الصحيح.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top