How do I mock a static method that returns void with PowerMock?

前端 未结 4 1271
傲寒
傲寒 2020-12-02 09:41

I have a few static util methods in my project, some of them just pass or throw an exception. There are a lot of examples out there on how to mock a static method that has a

相关标签:
4条回答
  • 2020-12-02 10:11

    You can stub a static void method like this:

    PowerMockito.doNothing().when(StaticResource.class, "getResource", anyString());
    

    Although I'm not sure why you would bother, because when you call mockStatic(StaticResource.class) all static methods in StaticResource are by default stubbed

    More useful, you can capture the value passed to StaticResource.getResource() like this:

    ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
    PowerMockito.doNothing().when(
                   StaticResource.class, "getResource", captor.capture());
    

    Then you can evaluate the String that was passed to StaticResource.getResource like this:

    String resourceName = captor.getValue();
    
    0 讨论(0)
  • 2020-12-02 10:11

    To mock a static method that return void for e.g. Fileutils.forceMKdir(File file),

    Sample code:

    File file =PowerMockito.mock(File.class);
    PowerMockito.doNothing().when(FileUtils.class,"forceMkdir",file);
    
    0 讨论(0)
  • 2020-12-02 10:27

    In simpler terms, Imagine if you want mock below line:

    StaticClass.method();
    

    then you write below lines of code to mock:

    PowerMockito.mockStatic(StaticClass.class);
    PowerMockito.doNothing().when(StaticClass.class);
    StaticClass.method();
    
    0 讨论(0)
  • 2020-12-02 10:29

    You can do it the same way you do it with Mockito on real instances. For example you can chain stubs, the following line will make the first call do nothing, then second and future call to getResources will throw the exception :

    // the stub of the static method
    doNothing().doThrow(Exception.class).when(StaticResource.class);
    StaticResource.getResource("string");
    
    // the use of the mocked static code
    StaticResource.getResource("string"); // do nothing
    StaticResource.getResource("string"); // throw Exception
    

    Thanks to a remark of Matt Lachman, note that if the default answer is not changed at mock creation time, the mock will do nothing by default. Hence writing the following code is equivalent to not writing it.

    doNothing().doThrow(Exception.class).when(StaticResource.class);
    StaticResource.getResource("string");
    

    Though that being said, it can be interesting for colleagues that will read the test that you expect nothing for this particular code. Of course this can be adapted depending on how is perceived understandability of the test.


    By the way, in my humble opinion you should avoid mocking static code if your crafting new code. At Mockito we think it's usually a hint to bad design, it might lead to poorly maintainable code. Though existing legacy code is yet another story.

    Generally speaking if you need to mock private or static method, then this method does too much and should be externalized in an object that will be injected in the tested object.

    Hope that helps.

    Regards

    0 讨论(0)
提交回复
热议问题