Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mocking whenNew using withAnyArguments does not match null arguments #891

Open
sgilhooly opened this issue Mar 15, 2018 · 1 comment
Open

Comments

@sgilhooly
Copy link

sgilhooly commented Mar 15, 2018

Using:

  • powermock-module-junit4 2.0.0-beta.5
  • powermock-api-mockito2 2.0.0-beta.5
  • mockito-core 2.16.0

I am having trouble using the whenNew(Class).withAnyArguments() when one of those arguments is null in the tested code. For example, the following test case is failing for me:

package org.mypackage;

import org.apache.http.HttpResponse;
import org.apache.http.ReasonPhraseCatalog;
import org.apache.http.StatusLine;
import org.apache.http.message.BasicHttpResponse;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

import static org.mockito.Mockito.mock;
import static org.powermock.api.mockito.PowerMockito.whenNew;

@RunWith(PowerMockRunner.class)
@PrepareForTest({BasicHttpResponse.class})
public class TestNullArgument {

    @Test
    public void testReproduce() throws Exception {

        final BasicHttpResponse testResponse = mock(BasicHttpResponse.class);
        whenNew(BasicHttpResponse.class).withAnyArguments().thenReturn(testResponse);

        // Note the 3rd argument 'null' which I expect would match when using 'withAnyArgument'
        HttpResponse r = new BasicHttpResponse(mock(StatusLine.class), mock(ReasonPhraseCatalog.class), null);

        Assert.assertNotNull("The newly allocated (mocked) value should not be null", r);
    }
}

This test example should pass but because the withAnyArguments() generates incorrect constructor argument matchers, the new returns null and the assertion fails.

I have tried to examine this under the debugger and I am able to determine that the the "expected" matches are getting generated as: [any(StatusLine.class), any(ReasonPhraseCatalog.class), any(Locale.class)] which causes it to not match the third null parameter, since null is not instanceof(Locale.class).

I'm having a hard time figuring out where it generated the list of argument matchers though to find the bug.

@sgilhooly
Copy link
Author

For what it's worth I reproduced this problem with the latest HEAD of branch release/2.x (version 2.0.0-beta.8).

When an object has multiple constructors, this code in withAnyArguments generates matchers for the first constructor and matchers for the remaining constructors are generated somewhere else (during the thenReturn flow somewhere I haven't found yet). The first constructor's matchers are generated properly (using the form or(isA(Class), isNull())). But the remaining constructors are not (they only have any(Class) which causes them to not match against nullvalues).

So if the constructor you need mocked happens to be the first one the withAnyArguments code picks up, then the test will work. But it's easy to get unlucky and get stuck with a different constructor which has the incorrect matchers.

sgilhooly pushed a commit to sgilhooly/powermock that referenced this issue Mar 16, 2018
Fix for powermock#891 which prevented null arguments from matching with
generated constructor matchers.
sgilhooly pushed a commit to sgilhooly/powermock that referenced this issue Mar 16, 2018
…ments

Fixes construcotr generated matchers to include allowance for
null arguments.
sgilhooly pushed a commit to sgilhooly/powermock that referenced this issue Mar 16, 2018
…ments

Fixes generated matchers for constructors to include allowance for
null arguments.
sgilhooly pushed a commit to sgilhooly/powermock that referenced this issue Mar 16, 2018
…ments

Fixes generated matchers for constructors to include allowance for
null arguments.
sgilhooly pushed a commit to sgilhooly/powermock that referenced this issue Mar 16, 2018
…uments

Fixes generated matchers for constructors to include allowance for
null arguments.
thekingn0thing pushed a commit that referenced this issue Mar 20, 2018
Fixes generated matchers for constructors to include allowance for
null arguments.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant