මොකිටෝ සමඟ අවලංගු ක්‍රම සමච්චල් කරන්නේ කෙසේද


961

අවලංගු ආපසු වර්ගයක් සමඟ ක්‍රම සමච්චල් කරන්නේ කෙසේද?

මම නිරීක්ෂක රටාවක් ක්‍රියාත්මක කළ නමුත් මට එය මොකිටෝ සමඟ සමච්චල් කළ නොහැක.

මම අන්තර්ජාලයේ උදාහරණයක් සොයා ගැනීමට උත්සාහ කළ නමුත් එය සාර්ථක වූයේ නැත.

මගේ පන්තිය මේ වගේ ය:

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();
}

පද්ධතිය සමච්චලයට ලක් නොවේ.

ඉහත පද්ධති පද්ධතියේ තත්වය පෙන්වීමට මට අවශ්‍යය. ඔවුන්ට අනුව ප්‍රකාශ කරන්න.


7
සමච්චල් කිරීමේ අවලංගු ක්‍රම පෙරනිමියෙන් කිසිවක් නොකරන බවට වග බලා ගන්න!
පේළිය

1
Line ලයින්, ඒකයි මම හොයන්නේ. ඔබ එය පැවසීමෙන් පසු එය පැහැදිලිව පෙනේ. නමුත් එය සමච්චල් කිරීමේ මූලධර්මයක් ඉස්මතු කරයි: ඔබට අවශ්‍ය වන්නේ සමච්චල් කරන ලද පංතිවල ප්‍රති effects ල විග්‍රහ කිරීම පමණි. ඔබට ස්තුතියි!
ඇලෙන්ජොම්

Answers:


1177

Mockito API ලියකියවිලි දෙස බලන්න . සම්බන්ධිත ලේඛනයක් ලෙස (පේදුරු # 12) සඳහන් ඔබ ඕනෑම භාවිතා කළ හැකිය doThrow(), doAnswer(), doNothing(), doReturn()Mockito රාමුව සිට ක්රම ව්යාජ අඩුව ක්රම පවුල.

උදාහරණයක් වශයෙන්,

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

හෝ පසු විපරම් හැසිරීම සමඟ එය ඒකාබද්ධ කිරීමට ඔබට අවශ්‍ය නම්,

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

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());

9
alqualidafial: ඔව්, මම ආපසු එන වර්ගය ගැන උනන්දුවක් නොදක්වන බව වඩා හොඳින් ප්‍රකාශ කරන බැවින් Void සඳහා පරාමිතිකරණය වඩා හොඳ වනු ඇතැයි මම සිතමි. මෙම ඉදිකිරීම ගැන මා දැන සිටියේ නැත, එය පෙන්වා දීමට ස්තූතියි.
sateesh

2
doThrow දැන් 5 වන ස්ථානයේ සිටී (මට ද doThrow භාවිතා කිරීමෙන් මෙය "අවලංගු" වර්ගය මෙහි අවසර නැත ", අනුගාමිකයින් සඳහා
සවි කර ඇත

alqualidafial: මම හිතන්නේ Answer.answer ඇමතුමේ මුල් වර්ගය මුල් ක්‍රමයට නැවත ලැබෙන්නේ කුමක්ද යන්න නොවේ, එය doAnswer ඇමතුම වෙත ආපසු යවනු ලැබේ, ඔබේ පරීක්ෂණයේදී එම අගය සමඟ වෙනත් යමක් කිරීමට ඔබට අවශ්‍ය නම්.
දොළොස් 17

1
:( ගුවා ඩොනොටිං () හි රේට්ලිමිටර්.ජාවා හි 16.0.1 අනුවාදය මොක් කිරීමට උත්සාහ කිරීමේදී. එය මගේ සෙට් රේට් ක්‍රමයට සරදම් කළේ නැත :( ඒ වෙනුවට එය හැඳින්වූයේ :(
ඩීන් හිලර්

2
බව @DeanHiller දැනුම් setRate()වේ final, එම නිසා ඔහුට සමච්චල් කළ නොහැකිය. ඒ වෙනුවට create()ඔබට අවශ්‍ය දේ කරන උදාහරණයක් උත්සාහ කරන්න . සමච්චල් කිරීමේ අවශ්‍යතාවයක් නොතිබිය යුතුය RateLimiter.
dimo414

116

මම හිතන්නේ මම එම ප්‍රශ්නයට සරල පිළිතුරක් සොයාගෙන ඇති අතර, එක් ක්‍රමයක් සඳහා සැබෑ ක්‍රමය ඇමතීමට (එය අවලංගු ප්‍රතිලාභයක් තිබුණත්) ඔබට මෙය කළ හැකිය:

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

නැතහොත්, ඔබට එම පන්තියේ සියලුම ක්‍රම සඳහා සැබෑ ක්‍රමය අමතන්න, මෙය සිදු කිරීම:

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

13
මෙහි නියම පිළිතුර මෙයයි. ඔත්තු () ක්‍රමය හොඳින් ක්‍රියාත්මක වන නමුත් සාමාන්‍යයෙන් වෙන් කර ඇත්තේ වස්තුව සාමාන්‍යයෙන් බොහෝ දේ කිරීමට ඔබට අවශ්‍ය විටදීය.
biggusjimmus

1
මෙමගින් කුමක් වෙයිද? ඔබ ඇත්තටම ක්‍රම අමතන්නේද? මම මීට පෙර ඇත්තටම මොකිටෝ භාවිතා කර නැත.
obesechicken13

ඔව්, සමච්චල් කිරීම සැබෑ ක්‍රම ලෙස හැඳින්වේ. ඔබ ockMock භාවිතා කරන්නේ නම්, ඔබට මෙයම සඳහන් කළ හැකිය: ockMock (answer = Answers.CALLS_REAL_METHODS) එකම ප්‍රති .ල ලබා ගැනීම සඳහා.
අලේ

74

Ate සතීෂ් පැවසූ දෙයට එකතු කරමින්, පරීක්ෂණය කැඳවීම වැළැක්වීම සඳහා ඔබට අවලංගු ක්‍රමයක් සමච්චල් කිරීමට අවශ්‍ය වූ විට, ඔබට Spyමේ ආකාරයෙන් භාවිතා කළ හැකිය:

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

ඔබේ පරීක්ෂණය ක්‍රියාත්මක කිරීමට ඔබට අවශ්‍ය වූ විට, ඔබ එම ක්‍රමය පරීක්‍ෂා කිරීමේ ක්‍රමය spyවස්තුව මත නොව වස්තුව මත කැඳවීමට වග බලා ගන්න world. උදාහරණයක් වශයෙන්:

assertEquals(0, spy.methodToTestThatShouldReturnZero());

59

ඊනියා ප්රශ්නය විසඳීම සඳහා භාවිතා කිරීමයි spy Mockito.spy (...) ඒ වෙනුවට ක mock Mockito.mock (..) .

ඔත්තු බැලීම අපට අර්ධ සමච්චලයට ලක් කරයි. මොකිටෝ මේ කාරණයේදී හොඳයි. ඔබට සම්පූර්ණ නොවන පන්තියක් ඇති හෙයින්, මේ ආකාරයෙන් ඔබ මෙම පන්තියේ අවශ්‍ය ස්ථානයක් සමච්චලයට ලක් කරයි.


3
මට මෙවැනිම ගැටළුවක් ඇති වූ නිසා මම මෙහි පැකිලී ගියෙමි (අහම්බෙන්, විෂය / නිරීක්ෂක අන්තර්ක්‍රියා පරීක්‍ෂා කිරීමද සිදුවිය). මම දැනටමත් ඔත්තුකරුවෙකු භාවිතා කරමි, නමුත් මට අවශ්‍ය වන්නේ 'SubjectChanged' ක්‍රමය වෙනස් දෙයක් කිරීමටය. ක්‍රමවේදය හැඳින්වූයේ දැයි බැලීමට මට `සත්‍යාපනය (නිරීක්ෂකයා) භාවිතා කළ හැකිය. විෂයය වෙනස් විය (විෂය). නමුත්, කිසියම් හේතුවක් නිසා, මම ක්‍රමවේදය ඉක්මවා යන්නෙමි. ඒ සඳහා සතීෂ්ගේ ප්‍රවේශය හා ඔබේ පිළිතුර මෙහි යා යුතු මාර්ගය විය ...
gMale

33
නැත, මෙය කිරීමෙන් අවලංගු අවලංගු ක්‍රමවලට උපකාරී නොවේ. උපක්‍රමය වන්නේ සතීෂ්ගේ පිළිතුරෙහි ලැයිස්තුගත කර ඇති මොකිටෝ ස්ථිතික ක්‍රම හතරෙන් එකක් භාවිතා කිරීමයි.
ඩාවුඩ් ඉබ්න් කරීම්

2
Question ඔබේ ප්‍රශ්නය සඳහා ගර්නාර්ඩ් මෙම stackoverflow.com/questions/1087339/… බලන්න .
ibrahimyilmaz

38

පළමුවෙන්ම: ඔබ සැමවිටම මොකිටෝ ස්ථිතික ආනයනය කළ යුතුය, මේ ආකාරයෙන් කේතය වඩාත් කියවිය හැකි (සහ බුද්ධිමත්) වනු ඇත:

import static org.mockito.Mockito.*;

අර්ධ වශයෙන් සමච්චල් කිරීම සහ ඉතිරි ක්‍රියාකාරිත්වය මත තවමත් මුල් ක්‍රියාකාරිත්වය තබා ගැනීම සඳහා "ස්පයි" ඉදිරිපත් කරයි.

ඔබට එය පහත පරිදි භාවිතා කළ හැකිය:

private World world = spy(new World());

ක්රමයක් ක්රියාත්මක කිරීමෙන් ඉවත් කිරීම සඳහා ඔබට මෙවැනි දෙයක් භාවිතා කළ හැකිය:

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

ක්‍රමයකට යම් අභිරුචි හැසිරීමක් ලබා දීමට “එවිට” “පසුව නැවත පැමිණීම” සමඟ භාවිතා කරන්න:

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

තවත් උදාහරණ සඳහා කරුණාකර ලේඛනයේ ඇති විශිෂ්ට මොකිටෝ සාම්පල සොයා ගන්න.


4
ස්ථිතික ආනයනය වඩාත් කියවිය හැකි බවට පත්කිරීමට කුමක් කළ යුතුද?
jsonbourne

2
වචනාර්ථයෙන් කිසිවක් නැත.
specializt

3
මම හිතන්නේ එය රසයේ කාරණයක්, මම කැමතියි ඉංග්‍රීසි වාක්‍යයක් මෙන් (පාහේ) ප්‍රකාශය ලබා ගැනීමට, සහ Class.methodname (). යමක් () එදිරිව.
fl0w

1
ඔබ කණ්ඩායමක වැඩ කරන්නේ නම්, ආනයන ස්ථිතිකය වෙනත් ඕනෑම කෙනෙකුට මෙම ක්‍රමය පැමිණෙන්නේ කොතැනින් දැයි බැලීමට වේදනාවක් ගෙන දෙයි, මන්ද බොහෝ විට ආනයනයේ ආදේශක කාඩ්පතක් ඇත.
LowKeyEnergy

1
එය නිවැරදි ය, කෙසේ වෙතත් ටෙස්ට් කේතය සහ මොකිටෝ සඳහා මෙය පැහැදිලි විය යුතු අතර ගැටළුවක් නොවේ.
fl0w

27

මොකිටෝ සමඟ අවලංගු ක්‍රම සමච්චල් කරන්නේ කෙසේද - විකල්ප දෙකක් තිබේ:

  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 (උදාහරණ සහිත සම්පූර්ණ මගපෙන්වීමක්) සමග සමච්චල් කෙසේද


1
විශිෂ්ට උදාහරණය. සටහන: ජාවා 8 හි, නිර්නාමික පංතියක් වෙනුවට ලැම්බඩා භාවිතා කිරීම ටිකක් හොඳ විය හැකිය: 'doAnswer ((පිළිතුර <Void>) ආයාචනය -> {// CODE}). විට (mockInstance) .add (ක්‍රමය) ()); '
miwe

16

පොකුරට තවත් පිළිතුරක් එක් කිරීම (කිසිදු ද pun ුවමක් අපේක්ෂා නොකරයි) ...

ඔත්තු බැලීමට භාවිතා කිරීමට ඔබට අවශ්‍ය නැතිනම් ඔබට doAnswer ක්‍රමය අමතන්න. කෙසේ වෙතත්, ඔබට ඔබේම පිළිතුරක් පෙරළීමට අවශ්‍ය නොවේ . පෙරනිමි ක්‍රියාත්මක කිරීම් කිහිපයක් තිබේ. සැලකිය යුතු CallsRealMethods .

ප්රායෝගිකව, එය මේ වගේ දෙයක් පෙනේ:

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

හෝ:

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

16

ජාවා 8 හි ඔබට ස්ථිතික ආනයනයක් ඇතැයි උපකල්පනය කරමින් මෙය ටිකක් පිරිසිදු කළ හැකිය org.mockito.Mockito.doAnswer:

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

මෙම return null;වැදගත් වන අතර එය තොරව එක්රැස් ඒ සඳහා සුදුසු අභිබවා සොයා ගැනීමට නොහැකි වනු ඇත සමහර තරමක් අප්රකට දෝෂ සහිත අසාර්ථක වනු ඇත doAnswer.

නිදසුනක් ලෙස සම්මත කර ඇති ExecutorServiceඕනෑම දෙයක් වහාම ක්‍රියාත්මක කළ හැකිය.Runnableexecute()

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

2
එක් පේළියක: Mockito.doAnswer ((i) -> null) .එහි (උදාහරණය) .මෙතෝඩ් (ඕනෑම ());
අක්ෂේ තෝර්ව්

@ අක්ෂයිතෝර්ව් ඔබට ඇත්ත වශයෙන්ම මා සමඟ දේවල් කිරීමට අවශ්‍ය වූ විට එය ක්‍රියා නොකරයි.
ටිම් බී

7

මම හිතන්නේ ඔබේ ගැටළු වලට හේතුව ඔබේ පරීක්ෂණ ව්‍යුහයයි. පරීක්ෂණ පන්තියේ අතුරුමුහුණත් ක්‍රියාත්මක කිරීමේ සාම්ප්‍රදායික ක්‍රමය සමඟ සමච්චල් කිරීම මිශ්‍ර කිරීම මට අපහසු විය (ඔබ මෙහි කළ පරිදි).

ඔබ සවන්දෙන්නෙකු විහිළුවක් ලෙස ක්‍රියාත්මක කරන්නේ නම් ඔබට අන්තර්ක්‍රියා සත්‍යාපනය කළ හැකිය.

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

'ලෝකය' නිවැරදි දේ කරන බවට මෙය ඔබව තෘප්තිමත් කළ යුතුය.


1

Mockito.doThrow භාවිතා කිරීම:

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

ඔබට මෙම කදිම උදාහරණය උත්සාහ කළ හැකිය:

public void testCloseStreamOnException() throws Exception {
    OutputStream outputStream = Mockito.mock(OutputStream.class);
    IFileOutputStream ifos = new IFileOutputStream(outputStream);
    Mockito.doThrow(new IOException("Dummy Exception")).when(outputStream).flush();
    try {
      ifos.close();
      fail("IOException is not thrown");
    } catch (IOException ioe) {
      assertEquals("Dummy Exception", ioe.getMessage());
    }
    Mockito.verify(outputStream).close();
  }

මුලාශ්‍රය: http://apisonar.com/java-examples/org.mockito.Mockito.doThrow.html#Example-19

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.