How to use real classes and mockito at the same time?

Eduardo Wada :

I'm trying run a unit test with Mockito, but I have a helper method where I want to use a real class:

public static Location fromCoordinates(float latitude, float longitude){
    Location result = new Location("");
    result.setLatitude(latitude);
    result.setLongitude(longitude);

    return result;
}

The method above currently causes a "Method ... not mocked." error as described here, it gives a suggestion on how to use default values, but that's not going to work for me since that causes the latitude and longitude to return 0 afterwards.

I also tried adding Mockito.mock(Location.class, CALLS_REAL_METHODS); at the beginning of my test which appears to have no effect.

How can I configure my test to use the real Location class while still using mockito to mock the others?

[Edit] For context, this is the unit test in question

@Test
public void OpensCenteredInLocation() {

    Location l = Mockito.mock(Location.class, CALLS_REAL_METHODS);

    //When the user starts the app
    LocationManager m = Mockito.mock(LocationManager.class);
    Location initial = LocationHelper.fromCoordinates(10, 15); //<--it fails here
    doReturn(initial).when(m).getLastKnownLocation(any(String.class));
    MyApp main = new MyApp(m);

    //Then it should open with the map centered in the user's location
    Assert.assertEquals(10, main.CameraPosition.longitude, 0);
    Assert.assertEquals(15, main.CameraPosition.longitude, 0);
}

When it fails, it throws java.lang.RuntimeException: Method setLatitude in android.location.Location not mocked. See http://g.co/androidstudio/not-mocked for details.

Oscar Emilio Perez Martinez :

I think the real problem is not because fromCoordinates method is static, in my opinion the real problem is because Location is a built-in Android class.

In fact when you run a unit test, it's being run on your computer, not on an Android device. So you cannot use the built-in Android classes.

Take a look at the android documentation

And then according to this doc told you that you could add to your build.gradle file

android {
  ...
  testOptions {
    unitTests.returnDefaultValues = true
  }
}

This prevents the android classes from throwing exceptions when you try to use them, but note that what this does is to

Change the behavior so that methods instead return either null or zero

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=28914&siteId=1