Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to mock objects created inside method?

Consider this

public class UserManager {
    private final CrudService crudService;

    @Inject
    public UserManager(@Nonnull final CrudService crudService) {
        this.crudService = crudService;
    }

    @Nonnull
    public List<UserPresentation> getUsersByState(@Nonnull final String state) {
        return UserPresentation.getUserPresentations(new UserQueries(crudService).getUserByState(state));
    }

}

I want to mock out

new UserQueries(crudService)  

so that I can mock out its behavior

Any ideas?

like image 795
daydreamer Avatar asked Oct 11 '14 22:10

daydreamer


People also ask

How do you mock an object in method?

Mockito mock method We can use Mockito class mock() method to create a mock object of a given class or interface. This is the simplest way to mock an object. We are using JUnit 5 to write test cases in conjunction with Mockito to mock objects.

How do you mock a method call inside another method in the same class?

We can mock runInGround(String location) method inside the PersonTest class as shown below. Instead of using mock(class) here we need to use Mockito. spy() to mock the same class we are testing. Then we can mock the method we want as follows.

How do you mock injected objects?

Mockito @InjectMocks annotations allow us to inject mocked dependencies in the annotated class mocked object. This is useful when we have external dependencies in the class we want to mock. We can specify the mock objects to be injected using @Mock or @Spy annotations.


2 Answers

With PowerMock you can mock constructors. See example

I'm not with an IDE right now, but would be something like this:

  UserQueries userQueries = PowerMockito.mock(UserQueries.class);
  PowerMockito.whenNew(UserQueries.class).withArguments(Mockito.any(CrudService.class)).thenReturn(userQueries);

You need to run your test with PowerMockRunner (add these annotations to your test class):

@RunWith(PowerMockRunner.class)
@PrepareForTest(UserQueries .class)

If you cannot use PowerMock, you have to inject a factory, as it says @Briggo answer.

Hope it helps

like image 160
troig Avatar answered Sep 24 '22 03:09

troig


You could inject a factory that creates UserQueries.

public class UserManager {
private final CrudService crudService;
private final UserQueriesFactory queriesFactory; 

@Inject
public UserManager(@Nonnull final CrudService crudService,UserQueriesFactory queriesFactory) {
    this.crudService = crudService;
    this.queriesFactory = queriesFactory;
}

@Nonnull
public List<UserPresentation> getUsersByState(@Nonnull final String state) {
    return UserPresentation.getUserPresentations(queriesFactory.create(crudService).getUserByState(state));
}

}

Although it may be better (if you are going to do this) to inject your CrudService into the factory.

like image 36
Briggo Avatar answered Sep 23 '22 03:09

Briggo