1. <i id='oIVg0'><tr id='oIVg0'><dt id='oIVg0'><q id='oIVg0'><span id='oIVg0'><b id='oIVg0'><form id='oIVg0'><ins id='oIVg0'></ins><ul id='oIVg0'></ul><sub id='oIVg0'></sub></form><legend id='oIVg0'></legend><bdo id='oIVg0'><pre id='oIVg0'><center id='oIVg0'></center></pre></bdo></b><th id='oIVg0'></th></span></q></dt></tr></i><div id='oIVg0'><tfoot id='oIVg0'></tfoot><dl id='oIVg0'><fieldset id='oIVg0'></fieldset></dl></div>

    1. <tfoot id='oIVg0'></tfoot>
      <legend id='oIVg0'><style id='oIVg0'><dir id='oIVg0'><q id='oIVg0'></q></dir></style></legend>

      <small id='oIVg0'></small><noframes id='oIVg0'>

        <bdo id='oIVg0'></bdo><ul id='oIVg0'></ul>

    2. 使用 PowerMock 模拟私有方法,但仍会调用底层方法

      时间:2023-09-26

      <small id='XvYDz'></small><noframes id='XvYDz'>

    3. <tfoot id='XvYDz'></tfoot>

            <tbody id='XvYDz'></tbody>
            <bdo id='XvYDz'></bdo><ul id='XvYDz'></ul>
              1. <i id='XvYDz'><tr id='XvYDz'><dt id='XvYDz'><q id='XvYDz'><span id='XvYDz'><b id='XvYDz'><form id='XvYDz'><ins id='XvYDz'></ins><ul id='XvYDz'></ul><sub id='XvYDz'></sub></form><legend id='XvYDz'></legend><bdo id='XvYDz'><pre id='XvYDz'><center id='XvYDz'></center></pre></bdo></b><th id='XvYDz'></th></span></q></dt></tr></i><div id='XvYDz'><tfoot id='XvYDz'></tfoot><dl id='XvYDz'><fieldset id='XvYDz'></fieldset></dl></div>

                <legend id='XvYDz'><style id='XvYDz'><dir id='XvYDz'><q id='XvYDz'></q></dir></style></legend>

                本文介绍了使用 PowerMock 模拟私有方法,但仍会调用底层方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

                问题描述

                我正在尝试模拟一个进行 JNDI 调用的私有方法.当从单元测试中调用该方法时,它会引发异常^.我想模拟该方法以进行测试.我使用了 来自另一个问题的示例代码回答,当测试通过时,似乎仍然调用了底层方法.我在 doTheGamble() 方法中插入了一个 System.err.println(),它被打印到我的控制台.

                I am trying to mock out a private method that is making a JNDI call. When that method gets called from a unit test, it throws an exception^. I would like to mock-out that method for testing purposes. I used the sample code from another questions answer, and while the test passes, it seems that the underlying method still gets called. I inserted a System.err.println() in the doTheGamble() method, and it gets printed out to my console.

                很有趣,如果我注释掉第一个 assertThat,测试就通过了.?:(

                Interesting enough, if I comment out the first assertThat, the test passes. ?:(

                那么,我如何模拟一个私有方法以使其不被调用?

                So, how do I mock out a private method so that it does not get called?

                import static org.hamcrest.core.Is.is;
                import static org.junit.Assert.assertThat;
                import static org.mockito.Matchers.anyInt;
                import static org.mockito.Matchers.anyString;
                import static org.powermock.api.mockito.PowerMockito.when;
                import static org.powermock.api.support.membermodification.MemberMatcher.method;
                
                import java.util.Random;
                
                import org.junit.Test;
                import org.junit.runner.RunWith;
                import org.powermock.api.mockito.PowerMockito;
                import org.powermock.core.classloader.annotations.PrepareForTest;
                import org.powermock.modules.junit4.PowerMockRunner;
                
                @RunWith(PowerMockRunner.class)
                @PrepareForTest(CodeWithPrivateMethod.class)
                public class PowerMock_Test {
                
                    static boolean gambleCalled = false; 
                
                    @Test(expected = RuntimeException.class)
                    public void when_gambling_is_true_then_always_explode() throws Exception {
                        CodeWithPrivateMethod spy = PowerMockito.spy(new CodeWithPrivateMethod());
                
                        when(spy, method(CodeWithPrivateMethod.class, "doTheGamble", String.class, int.class))
                                .withArguments(anyString(), anyInt())
                                .thenReturn(true);
                
                /* 1 */ assertThat( PowerMock_Test.gambleCalled, is(false) );
                        spy.meaningfulPublicApi();
                /* 2 */ assertThat( PowerMock_Test.gambleCalled, is(false) );
                    }
                }
                
                
                class CodeWithPrivateMethod {
                
                    public void meaningfulPublicApi() {
                        if (doTheGamble("Whatever", 1 << 3)) {
                            throw new RuntimeException("boom");
                        }
                    }
                
                    private boolean doTheGamble(String whatever, int binary) {
                        Random random = new Random(System.nanoTime());
                        boolean gamble = random.nextBoolean();
                
                        System.err.println( "
                >>> GAMBLE CALLED <<<
                " );
                        PowerMock_Test.gambleCalled = true;
                
                        return gamble;
                    }
                }   
                

                ^可以理解,因为我的工作区不支持JNDI,所以只有生产环境支持

                ^ understandably, since my workspace does not support JNDI, only the production environment does

                % 我正在使用所有库的最新版本,JUnit 4.10、Mockito 1.8.5、Hamcrest 1.1、Javassist 3.15.0 和 PowerMock 1.4.10.

                % I am using the latest versions of all the library, JUnit 4.10, Mockito 1.8.5, Hamcrest 1.1, Javassist 3.15.0, and PowerMock 1.4.10.

                推荐答案

                来自 PowerMock 私有方法示例:

                @RunWith(PowerMockRunner.class)
                // We prepare PartialMockClass for test because it's final or we need to mock private or static methods
                @PrepareForTest(PartialMockClass.class)
                public class YourTestCase {
                @Test
                public void privatePartialMockingWithPowerMock() {        
                    PartialMockClass classUnderTest = PowerMockito.spy(new PartialMockClass());
                
                    // use PowerMockito to set up your expectation
                    PowerMockito.doReturn(value).when(classUnderTest, "methodToMock", "parameter1");
                
                    // execute your test
                    classUnderTest.execute();
                
                    // Use PowerMockito.verify() to verify result
                    PowerMockito.verifyPrivate(classUnderTest, times(2)).invoke("methodToMock", "parameter1");
                }
                

                所以要将它应用到您的代码中,我认为它可能会变成:

                So to apply this to your code, I think it might become:

                @RunWith(PowerMockRunner.class)
                @PrepareForTest(CodeWithPrivateMethod.class)
                public class PowerMock_Test {
                    @Test(expected = RuntimeException.class)
                    public void when_gambling_is_true_then_always_explode() throws Exception {
                        CodeWithPrivateMethod spy = PowerMockito.spy(new CodeWithPrivateMethod());
                
                        PowerMockito.doReturn(true).when(spy, "doTheGamble", anyString(), anyInt());
                
                
                /* 1 */ PowerMockito.verifyPrivate(spy, times(0)).invoke("doTheGamble", anyString(), anyInt());            
                        spy.meaningfulPublicApi();
                /* 2 */ PowerMockito.verifyPrivate(spy, times(2)).invoke("doTheGamble", anyString(), anyInt());            
                    }
                }
                

                我只是在此处的编辑器中编写了代码.没有实际运行任何测试,并且在编写此代码时没有任何错误受到损害.

                I just coded that in the editor here. No tests have actually been run, and no bugs have been harmed in the crafting of this code.

                这篇关于使用 PowerMock 模拟私有方法,但仍会调用底层方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持html5模板网!

                上一篇:Mockito 验证不再与任何模拟交互 下一篇:如何模拟 void 静态方法以使用 Powermock 引发异常

                相关文章

                最新文章

                <small id='VGO6v'></small><noframes id='VGO6v'>

              2. <i id='VGO6v'><tr id='VGO6v'><dt id='VGO6v'><q id='VGO6v'><span id='VGO6v'><b id='VGO6v'><form id='VGO6v'><ins id='VGO6v'></ins><ul id='VGO6v'></ul><sub id='VGO6v'></sub></form><legend id='VGO6v'></legend><bdo id='VGO6v'><pre id='VGO6v'><center id='VGO6v'></center></pre></bdo></b><th id='VGO6v'></th></span></q></dt></tr></i><div id='VGO6v'><tfoot id='VGO6v'></tfoot><dl id='VGO6v'><fieldset id='VGO6v'></fieldset></dl></div>

                <tfoot id='VGO6v'></tfoot>

                  <legend id='VGO6v'><style id='VGO6v'><dir id='VGO6v'><q id='VGO6v'></q></dir></style></legend>
                  • <bdo id='VGO6v'></bdo><ul id='VGO6v'></ul>