Collectives™ on Stack Overflow
Find centralized, trusted content and collaborate around the technologies you use most.
Learn more about Collectives
Teams
Q&A for work
Connect and share knowledge within a single location that is structured and easy to search.
Learn more about Teams
@Stateless
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public class ClientRegistrationManager {
private CrudService crudService;
private UniqueIdGenerator uniqueIdGenerator;
@SuppressWarnings("UnusedDeclaration")
public ClientRegistrationManager() {
@Inject
public ClientRegistrationManager(@Nonnull final CrudService crudService, @Nonnull final UniqueIdGenerator uniqueIdGenerator) {
this.crudService = crudService;
this.uniqueIdGenerator = uniqueIdGenerator;
public Member register(@Nonnull final String email, @Nonnull final String userExternalId, @Nonnull final String password) {
final Member existingMember;
try {
existingMember = getMemberQueries().getMemberByEmail(email);
} catch (final NoResultException e) {
return createNewMemberAndGetClientDetail(email, userExternalId);
return existingMember;
@Nonnull
protected MemberQueries getMemberQueries() {
return new MemberQueries(crudService);
I wanted to test it by mocking out any external behavior, so I created getMemberQueries()
using Pattern - 1 described in doc
I, then write my test as following
public class ClientRegistrationManagerTest {
@Mock
private MemberQueries memberQueries;
@Mock
private CrudService crudService;
@Mock
private UniqueIdGenerator uniqueIdGenerator;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
@Test
public void testMockedMemberQueries() {
final ClientRegistrationManager clientRegistrationManager = new ClientRegistrationManager(crudService, uniqueIdGenerator);
Mockito.when(clientRegistrationManager.getMemberQueries()).thenReturn(memberQueries);
clientRegistrationManager.getMemberQueries();
assertTrue(true);
When I run this, I get the error as
org.mockito.exceptions.misusing.MissingMethodInvocationException:
when() requires an argument which has to be 'a method call on a mock'.
For example:
when(mock.getArticles()).thenReturn(articles);
Also, this error might show up because:
1. you stub either of: final/private/equals()/hashCode() methods.
Those methods *cannot* be stubbed/verified.
2. inside when() you don't call method on mock but on some other object.
3. the parent of the mocked class is not public.
It is a limitation of the mock engine.
Now what it means I need to mock out the entire ClientRegistrationManager
, but that the class I want to test, I can not just mock that entire class.
I am trying to understand my options here, I really do not want to depend on persistence
layer, that will be too heavy
–
–
–
–
Seelenvirtuose is correct in the comments: The root problem is that you can only call when
on mocks and spies, and that it is typically an anti-pattern to mock the class-under-test.
One technique is to use spy
, which lets you intercept and verify calls to a real object ("partial mocking"):
final ClientRegistrationManager clientRegistrationManager =
Mockito.spy(new ClientRegistrationManager(crudService, uniqueIdGenerator);
// doReturn is important because the call to contains a call to the mock
// before Mockito has intercepted it. In your case, this may just create a useless
// real MemberQueries, but in other cases it can throw an exception.
Mockito.doReturn(memberQueries).when(clientRegistrationManager).getMemberQueries();
As Predrag Magic wrote, another way to do this is to create a factory and replace that during the test. This is especially good if you pass in the factory as an optional constructor argument, because then production systems could create and pass in their own MemberQueryFactory and your class would still work as expected.
public class ClientRegistrationManager {
static class MemberQueriesFactory {
MemberQueries getMemberQueries() {
return ObjectFactory.newMemberQueries(crudService);
/** Package-private. Visible for unit testing. */
MemberQueriesFactory memberQueriesFactory = new MembersQueryFactory();
@RunWith(MockitoJUnitRunner.class)
public class ClientRegistrationManagerTest {
@Mock ClientRegistrationManager.MembersQueryFactory mockMembersQueryFactory;
private ClientRegistrationManager getManagerForTest() {
ClientRegistrationManager manager = new ClientRegistrationManager();
manager.memberQueriesFactory = mockMembersQueryFactory;
return manager;
My favorite way, though, is to skip Mockito and directly override the class-under-test in the test:
@RunWith(MockitoJUnitRunner.class)
public class ClientRegistrationManagerTest {
@Mock MemberQueries memberQueries;
private ClientRegistrationManager getManagerForTest() {
ClientRegistrationManager manager = new ClientRegistrationManager() {
@Override void getMemberQueries() {
return memberQueries;
–
One option is to use some kind of object factory to create new objects in classes under test, and then mock that factory.
protected MemberQueries getMemberQueries() {
return ObjectFactory.newMemberQueries(crudService);
If, for some reason, you want to mock just selected methods of some object instead of the whole object, you can do that with Mockito. Check out this example.
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.