why is mockito not called when executing mocked method? - java

Here is my test:
#Test
public void myTest() throws Exception {
String aVenueId = "1.2.3";
Venue2 aVenue = new Venue2(aVenueId);
VenuesRepository repository = mock(VenuesRepository.class);
when(repository.getVenue(anyString())).thenReturn(new VenueThumb(aVenue));
aMethodWithInnerCallToRepositoryGetVenue();
...
}
However when test runs my real code,
this line returns null (as there is no venue with venueId = "1.2.3"
that's why i used my mock for the first place).
public void aMethodWithInnerCallToRepositoryGetVenue(){
...
IVenue v = repository.getVenue(r.venueId);
..
}

You mocked a repository in your method, but this mock repository is assigned to a local variable only. So the code calling repository.getVenue() calls it on a different repository instance, and not on the one created by Mockito:
aMethodWithInnerCallToRepositoryGetVenue();
There's no way this method knows about the local variable initialized just before the method call.

As the user JB Nizet has written you are using two different instances of repository. You can do something like this: first you have a repository class you want to mock being a collaborator in the next class.
public class VenuesRepository {
public IVenue getVenue(String id) {
return new IVenue() {
// do something
};
}
}
Class Foo uses an instance of VenuesRepository as a collaborator which is not the objective of your unit test so you should mock its behavior when required.
public class Foo {
private VenuesRepository repository;
public Foo(VenuesRepository repo) {
repository = repo;
}
public IVenue getVenueFromRepository(String id) {
return repository.getVenue(id);
}
}
Now the test
public class FooTest {
#Test
public void testGetRepositoryWithMock() throws Exception {
String aVenueId = "1.2.3";
VenuesRepository repository = mock(VenuesRepository.class);
when(repository.getVenue(anyString())).thenReturn(mock(IVenue.class));
Foo foo = new Foo(repository);
assertNotNull(foo.getVenueFromRepository(aVenueId));
}
}
Now the instance of repository which has been mocked is the same.
I hope it helps.

Related

Test if another method is called from a class using JUnit or Mockito

I have a class like this
public class LoginPresImpl implements LoginAPIInterface.LoginDataListener, LoginAPIInterface.LoginPresenter{
LoginAPIInterface.LoginView loginView;
LoginAPIInterface.LoginDataInteractor loginDataInteractor;
public LoginPresImpl(LoginAPIInterface.LoginView loginView) {
this.loginView = loginView;
loginDataInteractor=new LoginDataModel(this);
}
#Override
public void getLoginUpdateData(String username, String password,String registrationToken) {
loginDataInteractor.getLoginData(username,password,registrationToken);
}
}
I want to test if calling
getLoginUpdateData()
will call the getLoginDate() method of loginDataInteractor.
I have created a test class like this
public class LoginPresImplTest {
LoginAPIInterface.LoginDataInteractor loginDataInteractorMock;
LoginAPIInterface.LoginView loginViewMock;
LoginPresImpl loginPres;
#Before
public void setUp(){
loginDataInteractorMock = Mockito.mock(LoginAPIInterface.LoginDataInteractor.class);
loginViewMock = Mockito.mock(LoginAPIInterface.LoginView.class);
loginPres = Mockito.spy(LoginPresImpl.class);
}
#Test
public void getLoginUpdateData() {
loginPres.getLoginUpdateData("01","","");
verify(loginPres).getLoginUpdateData("01","","");
}
But I don't know how to check if calling
getLoginUpdateData()
will eventually call
loginDataInteractor.getLoginData()
method. How can I test this using JUnit or Mockito.
I want to test if calling
getLoginUpdateData()
will call the getLoginDate() method of loginDataInteractor.
loginDataInteractor is a dependency of the code under test (cut) you showed.
In a UnitTest you only verify the behavior of the cut. You do not verify the behavior of the dependencies. They get their own unit tests.

Unit testing verify object returned from a callback in anonymous class

I'm new to unit testing and I'm not sure how to approuch this case, so I would appreciate your input.
Relevant code:
public class Repository {
#Override
public void getUnifiedFoo(#NonNull final Foo foo1,
#NonNull final GetUnifiedFooCallback getUnifiedFooCallback) {
fooDataSource.getFoo2(foo1,new GetFoo2Callback() {
#Override
public void onGetFooSuccess(Foo foo2) {
UnifiedFoo unifiedFoo= createUnifiedFoo(foo1, foo2);
getUnifiedFooCallback.onGetSuccess(unifiedFoo);
}
#Override
public void onGetMedicationCallbackFailure(Throwable t) {
getUnifiedFooCallback.onGetFailure(t);
}
});
}
}
private createUnifiedFoo(Foo foo1, Foo foo2){
return new UnifiedFoo(
foo1.getMember1,
foo1.getMember2,
foo2.getMember3,
foo2.getMember4,
);
}
My questions are:
Shoud 'createUnifiedFoo(Foo foo1, Foo foo2)' be package private and be tested separately?
In that context, if yes it sould, is there any point in testing that 1 methods (in this case fooDataSource.getFoo(...)) is called?
If it's acceptible to test 'createUnifiedFoo...' when getting called back in the anonymous class, how do I capture the callback so that when 'onGetFooSuccess(Foo foo2)' is called, I take foo1 stub, foo2 stub and assert equeal their fields to verfiy that they contain the correct values?
Thank you.
It's a matter of opinion actually.
Personally, I would move the createUnifiedFoo to a different class
class FooUnifier {
public UnifiedFoo of(Foo1 f1, Foo2 f2) {...
}
so in the repository you'd have
class Repository {
FooUnifier unifier = new FooUnifier(); // or #Autowired
...
getUnifiedFooCallback.onGetSuccess(unifier.of(foo1, foo2));
}
and in the unit test
#RunWith(MockitoJUnitRunner.class)
class Test {
#InjectMocks
Repository sut;
#Mock
FooDatasource datasource;
#Mock
FooUnifier unifier;
#Mock
UnifiedFoo unifiedFoo;
#Mock
GetUnifiedFooCallback callback;
#Before
public void mockUnifiedFoo()
when(unifier.of(any(), any())).thenReturn(unifiedFoo);
}
}
This will create mocks and set them to the Repository's member, allowing you to create test cases like this
#Test
public void unificationSuccess() {
Foo1 foo1 = mock(Foo1.class);
Foo2 foo2 = mock(Foo2.class);
when(datasource.getFoo2(foo1, eq(callback)))
.then(i -> {
callback.onGetSuccess(unifiedFoo);
});
sut.getUnifiedFoo(foo1, callback);
// make sure the unified foo was created
verify(unifier).of(foo1, foo2);
// make sure the callback was called
verify(callback).onGetSuccess(unifiedFoo);
}
so basically you setup your test case and then verify that all the correct calls are made with the right arguments.
You can test the correct behavior of the FooUnifier separately.

How to provide object inside public method to access another method within it using PowerMock?

I am writing unit test case for a Class
public class CurrentMoreInfoDataProvider implements CurrentMoreInfoInterface.presenterToModel{
private CurrentMoreInfoInterface.modelToPresenter modelToPresenter;
public CurrentMoreInfoDataProvider(CurrentMoreInfoInterface.modelToPresenter modelToPresenter) {
this.modelToPresenter = modelToPresenter;
}
#Override
public void provideData() {
WeatherApiResponsePojo apiWeatherData = WeatherDataSingleton.getInstance().getApiWeatherData();
if(null != apiWeatherData.getCurrently()){
CurrentlyPojo currently = apiWeatherData.getCurrently();
if(null != currently){
populateWeatherData(currently);
}
}
}
public void populateWeatherData(CurrentlyPojo currently) {....}
I want to just use verify method of power mock to test whether populateWeatherData get executed or not. Below is my test case so far.
#RunWith(PowerMockRunner.class)
#PrepareForTest(CurrentMoreInfoDataProvider.class)
public class TestCurrentMoreInfoDataProvider {
private CurrentMoreInfoDataProvider dataProvider;
#Mock
CurrentMoreInfoInterface.modelToPresenter modelToPresenter;
private CurrentlyPojo currentlyPojo = new CurrentlyPojo();
#Test
public void testPopulateWeatherData(){
dataProvider = PowerMockito.spy(new CurrentMoreInfoDataProvider(modelToPresenter));
dataProvider.provideData();
Mockito.verify(dataProvider).populateWeatherData(currentlyPojo);
}
}
If I run this I get null pointer exception in provideData method at
if(null != apiWeatherData.getCurrently()){
How should I provide apiWeatherData to provideData method in that class?
You have to mock WeatherDataSingleton.getInstance().getApiWeatherData() too.
This would be much easier if you would not use static access in general and the Singelton pattern in particular.
I tried mocking it, but how should i provide that mock object to provideData() ?
create a mock of WeatherDataSingleton.
Configure your Test so that this mock is used (by properly using dependency injection or by surrendering to your bad design using Powermock).
configure the mock to return the data:
doReturn(currentlyPojo).when(weatherDataSingletonMock).getApiWeatherData();
This resolves the NPE.
I dont think you need to go for PowerMockito if you apply a simple refactor to your production code:
public class CurrentMoreInfoDataProvider{
#Override
public void provideData() {
WeatherApiResponsePojo apiWeatherData = getApiWeatherData();
if(null != apiWeatherData.getCurrently()){
CurrentlyPojo currently = apiWeatherData.getCurrently();
if(null != currently){
populateWeatherData(currently);
}
}
}
WeatherApiResponsePojo getApiWeatherData(){
return WeatherDataSingleton.getInstance().getApiWeatherData();
}
then in your test expect that new method to return certain object:
#RunWith(MockitoJUnitRunner.class)
public class TestCurrentMoreInfoDataProvider {
private CurrentMoreInfoDataProvider dataProvider;
#Mock
CurrentMoreInfoInterface.modelToPresenter modelToPresenter;
#Mock
WeatherApiResponsePojo apiWeatherDataMock;
private CurrentlyPojo currentlyPojo = new CurrentlyPojo();
#Test
public void testPopulateWeatherData(){
dataProvider = PowerMockito.spy(new CurrentMoreInfoDataProvider(modelToPresenter));
doReturn(apiWeatherDataMock).when(dataProvider).getApiWeatherData();
dataProvider.provideData();
Mockito.verify(dataProvider).populateWeatherData(currentlyPojo);
}
}

Mocking a class assigns nulls to #NonNull fields(Android)

I'm using Android SDK and junit4 + Mockito for unit testing. Say I have a class like this in my app:
public class Container{
#NonNull private Set<String> values = new HashSet<>();
public void addValue(String value) {
values.add(value);
}
#NonNull
public Set<String> getValues() {
return values;
}
}
And I also have a unit test with Mockito that looks like this:
public class ContainerTest {
private Container container;
#Before
public void before() {
container = mock(Container.class);
}
#Test
public void shouldAddValue() {
container.add("test_value");
assertTrue(container.getValues.contains("test_value"));
}
}
This test actually fails on line "container.add("test_value");" because mock(Container.class) creates a class in which values field is actually set to null, so values.add(value) in addValue() method throws an NPE. I could add a null check in addValue() to fix this, but that seems absurd, since values are already declared non null.
Is there any way to make Mockito respect #NonNull annotations and initialize the field properly?
I think you aren't using Mockito in the right way, since you have to define the Mockito behaviors.
For instance, you should have something like this:
#Test
public void shouldAddValue() {
Set<String> mySet = new HashSet<String>();
mySet.put("test_value");
// Mock container getValues() method to return mySet
when(container.getValues()).thenReturn(mySet); // do import static for Mockito.when
assertTrue(container.getValues().contains("test_value"));
}
Mockito works pretty well when you mock responses, but what you want is to let Mockito to initialize classes for you which clearly it isn't Mockito goals.
Therefore, if you want to test your Container object, then you don't have to mock Container itself and you can have something like this:
public class ContainerTest {
private Container container;
#Before
public void before() {
container = new Container(); // Initialize container
}
#Test
public void shouldAddValue() {
container.addValue("test_value");
assertTrue(container.getValues().contains("test_value"));
}
}

Test a method which calls another method of the object in mockito

I have an interface, ex:
interface MyService {
void createObj(int id)
void createObjects()
}
I want to test an implementation of the createObjects method, which has body like:
void createObjects() {
...
for (...) {
createObj(someId);
}
}
I have already tested createObj(id):
#Test public void testCreate() {
//given
int id = 123;
DAO mock = mock(DAO.class);
MyService service = new MyServiceImpl(mock);
//when
service.createObj(id);
//verify
verify(mock).create(eq(id));
}
So I don't want to repeat all test cases for it in the test for createObjects.
How can I make sure that another method of the real object was called besides the one I am testing?
Use a spy:
MyService myService = new MyServiceImpl()
MyService spy = spy(myService);
doNothing().when(spy).createObj(anyInt());
// now call spy.createObjects() and verify that spy.createObj() has been called
This is described, like everything else, in the api doc.

Categories