When Using Mokito, Differencebetween the Actual Object and the Mocked Object

When using Mokito, what is the difference between the actual object and the mocked object?

Your test doesn't test any of your code. It tests that Mockito works fine.

When I introduce the concept of mocking, I take this example: suppose you build a detonator, and want to test it. You could of course use the detonator with a real bomb, and see if the whole block explodes when you use the detonator. But that isn't very practical. BTW, maybe you don't even have a bomb at your disposal. Maybe your colleague is still building it.

So you use a mock bomb. Note the important point: to test the detonator, you use a mock bomb. Not a mock detonator. What is mocked is the dependency of the class under test. Not the class under test itself.

What is a mock bomb? It's just a fake bomb that doesn't do anything. All it does is allowing to verify if has been asked to explode or not. So your code to test the detonator would be like this:

// create a mock bomb:
Bomb mockBomb = mock(Bomb.class);
// create a real detonator, but tie it to the mock bomb:
Detonator detonator = new Detonator(mockBomb);

// test the detonator. Since it's tied to a mock bomb, the block
// won't explode
detonator.pressTheRedButton();

// check it the mock bomb has been asked to explode, as it should
// if the detonator works correctly
verify(mockBomb).explode();

Now if the test passes, you know that all the internal circuitry that is used in pressTheRedButton() works fine and eventually tells the bomb to explode. So you know that, when used with a real bomb, the real bomb will be asked to explode as well when pressing the red button.

Now let's come back to the real world: you want to test a service, and this service uses a DAO that needs a database, populated with data, to run fine. To test your service, you can simply mock the DAO, and verify it works fine. The mock DAO can also be used as a stub, i.e. an object that returns what you tell it to return in the test, instead of actually querying the database. That's what you're doing in the code in your question: you're telling the mock MyClass instance that, when add() is called with 2 and 2 as arguments, it should return 4.

This makes the test easier to setup, faster to run, and independant from the actual code of the DAO, which is not what you want to test in the unit test of the service.

MockedObject and Real Object give different results

A mockito mock is an object having the interface of the mocked class, but not its implementation. Your StringChecker is mocked, meaning there is no implementation code making calls from isEqual to getSecretKey as you assume.

You could use mockito spy, See this SO question:

Mockito.spy() is a recommended way of creating partial mocks. The reason is it guarantees real methods are called against correctly constructed object because you're responsible for constructing the object passed to spy() method.

Mockito mocks refers to all object of the mocked class?

Sorry I got wrong. Only the instance explicitly mocked become a mock. The others are object of the real classes. I got wrong because of all the other mocked dependencies in the real class too.

So it's not true that if I mock an instance of a class, all the other instances of that class are instantiated as mocks. They are object of the real class.

Thank you for your useful answers, I apologize for the error.

Java Mockito is hitting real method rather than using mocked method

Your mistake is in broken 'Dependency injection' principle.

Don't use new operator - create UserDao at the level above and use injection.

public class CheckUser {
private final UserDao userDao;

public CheckUser (final UserDao usedDao) {
this.userDao = userDao;
}

public IUser getExistingUser() {
if (userDao == null) {
throw new RuntimeException("userDao is null");
}
IUser existingUser = userDao.getExistingUser();
if (existingUser == null) {
throw new RuntimeException("ExistingUser is null");
}
return existingUser;
}
}

Now you can test your code in the following way:

@Test
public void testExistingUser() {
UserDao mockUserDao = mock(UserDao.class);
when(mockUserDao.getExistingUser()).thenReturn(getExistingTestUser());

CheckUser checkUser = new CheckUser(mockUserDao);
IUser iUser = checkUser.getExistingUser();

// assertions here
}

private UserDao getExistingTestUser(() {
return ExistingUserImpl.Builder(). //withfield methods. build();
}

What is the difference between mocking and spying when using Mockito?

The answer is in the documentation:

Real partial mocks (Since 1.8.0)

Finally, after many internal debates & discussions on the mailing list, partial mock support was added to Mockito. Previously we considered partial mocks as code smells. However, we found a legitimate use case for partial mocks.

Before release 1.8 spy() was not producing real partial mocks and it was confusing for some users. Read more about spying: here or in javadoc for spy(Object) method.

callRealMethod() was introduced after spy(), but spy() was left there of course, to ensure backward compatibility.

Otherwise, you're right: all the methods of a spy are real unless stubbed. All the methods of a mock are stubbed unless callRealMethod() is called. In general, I would prefer using callRealMethod(), because it doesn't force me to use the doXxx().when() idiom instead of the traditional when().thenXxx()

Pass real object and mock object in constructor

Don't use @InjectMocks and simply do things by hand, like you almost are already:

AccountDetails sut = new AccountDetails(mockDependency, realObject);

Since @Mock and similar auto-wiring have to happen after the class is instantiated, if you need to refer to a mock during initialization, create it programmatically:

AccountDetailsRestClient mockRestClient = mock(AccountDetailsRestClient.class);

Mockito - difference between doReturn() and when()

The two syntaxes for stubbing are roughly equivalent. However, you can always use doReturn/when for stubbing; but there are cases where you can't use when/thenReturn. Stubbing void methods is one such. Others include use with Mockito spies, and stubbing the same method more than once.

One thing that when/thenReturn gives you, that doReturn/when doesn't, is type-checking of the value that you're returning, at compile time. However, I believe this is of almost no value - if you've got the type wrong, you'll find out as soon as you run your test.

I strongly recommend only using doReturn/when. There is no point in learning two syntaxes when one will do.

You may wish to refer to my answer at Forming Mockito "grammars" - a more detailed answer to a very closely related question.

why Mock object has doreturn and thenreturn for mock?

After doing by my own I came to know that:

  1. doreturn/when and when/thenreturn are same for mocked object. None of them call the actual method
  2. doreturn/when and when/thenreturn have different behaviour for spied object.
    doreturn/when - it will not call real method on spied object
    when/thenreturn - it will call real method on spied object

Hope it helps!



Related Topics



Leave a reply



Submit