Cannot mock URL class using PowerMockito / Mockito

I'm trying to use PowerMockito to make fun of creating a java.net.URL class in my code that I'm testing. Basically, I want a real HTTP request not to occur, and instead: 1) check the data when the request is executed and 2) return my own test data back to the mocked reaction. This is what I am trying:

@RunWith(PowerMockRunner.class) @PrepareForTest({ URL.class, MockedHttpConnection.class }) public class Test { URL mockedURL = PowerMockito.mock(URL.class); MockedHttpConnection mockedConnection = PowerMockito.mock(MockedHttpConnection.class); ... PowerMockito.whenNew(URL.class).withParameterTypes(String.class).withArguments("MyURLString").thenReturn(mockedURL); PowerMockito.when(mockedURL.openConnection()).thenReturn(mockedConnection); ... } 

The code I want to check is as follows:

 URL wlInvokeUrl = new URL(wlInvokeUrlString); connection = (HttpURLConnection) wlInvokeUrl.openConnection(); 

Earlier in my test case, I made fun of wlInvokeUrlString to match "MyURLString". I also tried using various other forms of the whenNew line, trying to introduce a layout. No matter what I try, it never intercepts the constructor. All I want to do is to β€œcatch” the openConnection () call and return its mocked HTTP connection instead of the real one.

I ridiculed the other classes before this in the same script, and they work as expected. Either I need a second pair of eyes (maybe true), or something unique about the URL class. I noticed that if I use "whenNew (URL.class) .withAnyArguments ()" and change "thenReturn" to "thenAnswer", I can get it to run. The only problem is that I never get the url of my code. What I see is a constructor call with 3 arguments for URL.class with all zeros for the parameters. Could this class be from the Java runtime and loaded by a test runner? Any help is greatly appreciated.

+5
source share
3 answers

I'm not sure what the difference is between .withParameterTypes(x) and .withArguments(x) , but I believe that you need to configure it like this in order for your code to work. Try it and let me know if this does not help.

 PowerMockito.when(mockedURL.openConnection()).thenReturn(mockedConnection); PowerMockito.whenNew(URL.class).withArguments(Mockito.anyString()).thenReturn(mockedURL); 
0
source

The problem is that the arguments to the real call do not match what was expected in your layout.

PowerMockito.whenNew(URL.class).withParameterTypes(String.class).withArguments("MyURLString").thenReturn(mockedURL) will return mockedURL only calling new URL("MyURLString") .

If you change it to:

 PowerMockito.whenNew( URL.class ).withParameterTypes( String.class ) .withArguments( org.mockito.Matchers.any( String.class ) ).thenReturn( mockedURL ); 

It will catch any string passed to the URL(String) constructor URL(String) (even null ) and return your layout.


When did you try

"whenNew (URL.class) .withAnyArguments ()" and change the value of "thenReturn" to "thenAnswer" I could make it call. Only problem is that I never get the url of my code. What I see is a 3-argument constructor call for URL.class with all zeros for the Parameters.

PowerMock will try to mock all the constructors ( org.powermock.api.mockito.internal.expectation.DelegatingToConstructorsOngoingStubbing.InvokeStubMethod on line 122), then it calls the first (with three arguments) and makes fun of its answer. But subsequent calls will return what is already being bullied, because you told him to mock any arguments. This is why you see only one call with null, null, null in Answer .

0
source

This is a common mistake when using PowerMockito.whenNew .

Note that you must prepare the class that creates a new instance of MyClass for the test, not MyClass. For instance. if the class executing the new MyClass () is called X, then you will need @PrepareForTest (X.class) in order for NewNew to work

From the Powermock wiki

So, you need to modify your test a bit and add a class to @PrepareForTest that creates a new URL instance, for example:

 @RunWith(PowerMockRunner.class) @PrepareForTest({ URL.class, MockedHttpConnection.class , ConnectionUser.class}) public class URLTest { public class URLTest { private ConnectionUser connectionUser; @Before public void setUp() throws Exception { connectionUser = new ConnectionUser(); } @Test public void testName() throws Exception { URL mockedURL = PowerMockito.mock(URL.class); MockedHttpConnection mockedConnection = PowerMockito.mock(MockedHttpConnection.class); PowerMockito.whenNew(URL.class).withParameterTypes(String.class).withArguments("MyURLString").thenReturn(mockedURL); PowerMockito.when(mockedURL.openConnection()).thenReturn(mockedConnection); connectionUser.open(); assertEquals(mockedConnection, connectionUser.getConnection()); } } 

Where:

 public class ConnectionUser { private String wlInvokeUrlString = "MyURLString"; private HttpURLConnection connection; public void open() throws IOException { URL wlInvokeUrl = new URL(wlInvokeUrlString); connection = (HttpURLConnection) wlInvokeUrl.openConnection(); } public HttpURLConnection getConnection() { return connection; } } 
0
source

Source: https://habr.com/ru/post/1243423/


All Articles