43
A Simple, Intuitive Mocking Framework

Mockito a simple, intuitive mocking framework

  • Upload
    phat-vu

  • View
    288

  • Download
    17

Embed Size (px)

Citation preview

Page 1: Mockito   a simple, intuitive mocking framework

A Simple, Intuitive Mocking Framework

Page 2: Mockito   a simple, intuitive mocking framework

www.axon.vn fb.com/AxonActiveVietNam

• Refresh the importance of unit testing

• Mock framework

• Mock with Mockito API

• Configuring Mockito in a Project

• Creating Mock

• Stubbing Method‟s Returned Value

• Argument Matching

• And more...

• Conclusion and Q&A

Mocks with Mockito API

Agenda

2/41

Page 3: Mockito   a simple, intuitive mocking framework

www.axon.vn fb.com/AxonActiveVietNam

Refresh : the importance of Unit testing

3/41 Mocks with Mockito API

Page 4: Mockito   a simple, intuitive mocking framework

www.axon.vn fb.com/AxonActiveVietNam

• Help to ensure that code meets requirements

• Could be considered a form of documentations as to how

the system currently operates.

• Help to ensure that changes made by the enhancement do

not break the existing system.

• Encourage refactoring.

• Integrate with Continuous Integration

• Improve design

Refresh : the importance of Unit testing

4/41 Mocks with Mockito API

Page 5: Mockito   a simple, intuitive mocking framework

www.axon.vn fb.com/AxonActiveVietNam

• The „hello world‟ has no dependencies on outside classes.

• Software has dependencies.

• The dependencies have not implemented yet.

• The idea of UT : test our code without testing the

dependencies

Problem…

Action classes (Testing)

Service classes

DAO classes

Dependencies of Action classes

5/41 Mocks with Mockito API

Page 6: Mockito   a simple, intuitive mocking framework

www.axon.vn fb.com/AxonActiveVietNam

• Didn’t write unit testing for my code

• Dependencies have been implemented

• Invoke dependencies directly in unit test.

• It‟s not unit test anymore ( integration test instead )

• Dependencies have NOT been implemented yet.

• Wait for some guys implementing the dependencies first.

• Hard code return value of the dependencies.

How I ‘solve’ the problem before ?

6/41 Mocks with Mockito API

Page 7: Mockito   a simple, intuitive mocking framework

www.axon.vn fb.com/AxonActiveVietNam Mocks with Mockito API 7/41

Page 8: Mockito   a simple, intuitive mocking framework

www.axon.vn fb.com/AxonActiveVietNam

HOW

Mocks with Mockito API 8/41

Page 9: Mockito   a simple, intuitive mocking framework

www.axon.vn fb.com/AxonActiveVietNam

MOCK FRAMEWORK

Mocks with Mockito API

“ Do One Thing and Do It Well “ Dan North

9/41

Page 10: Mockito   a simple, intuitive mocking framework

www.axon.vn fb.com/AxonActiveVietNam

In one sentence

What mock is ?

Mocks with Mockito API

“Mocks are object that simulates the behavior of real an object.”

“break dependencies of your classes”

10/41

Page 11: Mockito   a simple, intuitive mocking framework

www.axon.vn fb.com/AxonActiveVietNam

Why mock ?

Mocks with Mockito API

• Break dependencies.

• Parallel working.

• Do not need to modify code to “hard code” returning value of

dependencies.

• Run unit testing faster.

• Improve code design.

• Have fun in unit testing.

11/41

Page 12: Mockito   a simple, intuitive mocking framework

www.axon.vn fb.com/AxonActiveVietNam

• The real object is

• Difficult to setup

• Has behavior that is hard to trigger

• Slow

• User interface

• Some cases

• Dependencies are sensitive resources in real code.

• Charge money on API calls / API limit.

• Database accessing / Network interaction.

When I can use mock?

Mocks with Mockito API 12/41

Page 13: Mockito   a simple, intuitive mocking framework

www.axon.vn fb.com/AxonActiveVietNam

Mock model

Mocks with Mockito API

Action classes (Testing)

Service classes

DAO classes

Action classes (Testing)

Mock Service classes

Mock DAO

classes

Without mock

With mock

13/41

Page 14: Mockito   a simple, intuitive mocking framework

www.axon.vn fb.com/AxonActiveVietNam Mocks with Mockito API 14/41

Page 15: Mockito   a simple, intuitive mocking framework

www.axon.vn fb.com/AxonActiveVietNam

Mocks API ( Java )

Mocks with Mockito API 15/41

Page 16: Mockito   a simple, intuitive mocking framework

www.axon.vn fb.com/AxonActiveVietNam

In my opinion is

What is the selected ?

• Easy to use

• Simple & clean syntax

• Excellent documentation

See more on SO

Why ?

Mocks with Mockito API

“Mockito really cleans up the unit test by not requiring expectations. Personally, I much prefer the Mockito API to the EasyMock API for that reason.” - Hamlet D'Arcy

16/41

Page 17: Mockito   a simple, intuitive mocking framework

www.axon.vn fb.com/AxonActiveVietNam

Install Mockito

Maven <dependency>

<groupId>org.mockito</groupId>

<artifactId>mockito-all</artifactId>

<version>1.10.17</version> </dependency>

Gradle 'org.mockito:mockito-all:1.10.17'

In your code, import import static org.mockito.Mockito.*;

Mocks with Mockito API 17/41

Page 18: Mockito   a simple, intuitive mocking framework

www.axon.vn fb.com/AxonActiveVietNam

• The given : describes the state of the world before you begin

the behavior. You can think of it as the pre-conditions to the

test.

• The when : is that behavior that you're specifying.

• The then : describes the changes you expect due to the

specified behavior.

Given-When-Then is a style of representing tests, part of BDD

Given-When-Then

18/41 Mocks with Mockito API

Page 19: Mockito   a simple, intuitive mocking framework

www.axon.vn fb.com/AxonActiveVietNam

• A stub may simulate the behavior of existing code (Wikipedia)

• What's the difference between faking, mocking, and stubbing?

(view on SO)

Method stub

Mocks with Mockito API 19/41

Page 20: Mockito   a simple, intuitive mocking framework

www.axon.vn fb.com/AxonActiveVietNam

• mock(ClassToMock.class)

• when(methodCall)

• thenReturn(value)

• doReturn(value)

• thenThrow(Throwable)

• verify(mock).method(args)

• initMocks(this), @Mock, @Spy

Mockito - keywords

Mocks with Mockito API 20/41

Page 21: Mockito   a simple, intuitive mocking framework

www.axon.vn fb.com/AxonActiveVietNam

Without mock

@Test

public void test() throws Exception {

// Given

TestingObject testingObj = new TestingObject();

DependencyObject dependencyObj =

new DependencyObject();

// When

testingObject.doSomeThing(helper);

// Then

assertTrue(helper.somethingHappened());

}

Mocks with Mockito API 21/41

Page 22: Mockito   a simple, intuitive mocking framework

www.axon.vn fb.com/AxonActiveVietNam

Mockito "Template" Usage

@Test

public void test() throws Exception {

// Given (prepare behavior)

TestingObject testingObj = new TestingObject();

DependencyObject mockObj =

mock(DependencyObject.class);

when(mockObj.domesomething()).thenReturn(“A”);

// When

testingObject.doSomeThing(helper);

// Then (verify)

assertTrue(helper.somethingHappened());

}

Mocks with Mockito API 22/41

Page 23: Mockito   a simple, intuitive mocking framework

www.axon.vn fb.com/AxonActiveVietNam

• You can use Mockito to create mocks of a regular (not final)

class not only of an interface.

• Methods (include their arguments) that was not stubbed,

then return null when invoked. (See here)

Tips

Mocks with Mockito API 23/41

Page 24: Mockito   a simple, intuitive mocking framework

www.axon.vn fb.com/AxonActiveVietNam

That’s quite enough !

Let’s drink

Mocks with Mockito API 24/41

Page 25: Mockito   a simple, intuitive mocking framework

www.axon.vn fb.com/AxonActiveVietNam

Argument matchers

when(mockObject.dosomeThing(anyInt()).thenReturn(true);

• Mockito offer some built-in such as: anyString(), anyInt(),

any(Class<T> clazz), isNull, …

• Custom argument matchers (extends ArgumentMatcher)

If you are using argument matchers, all arguments have to

be provided by matchers.

Mocks with Mockito API 25/41

Page 26: Mockito   a simple, intuitive mocking framework

www.axon.vn fb.com/AxonActiveVietNam

In some situations, it is helpful to assert on certain arguments

after the actual verification

ArgumentCaptor

Mocks with Mockito API

ArgumentCaptor<Person> argument =

ArgumentCaptor.forClass(Person.class);

verify(mockObj).doSomething(argument.capture());

assertEquals("John", argument.getValue().getName());

In more details…

26/41

Page 27: Mockito   a simple, intuitive mocking framework

www.axon.vn fb.com/AxonActiveVietNam

Stubbing multiple calls to the same method

@Test

public void shouldReturnLastDefinedValueConsistently() {

WaterSource waterSource = mock(WaterSource.class);

when(waterSource.getWaterPressure()).thenReturn(3, 5);

assertEquals(waterSource.getWaterPressure(), 3);

assertEquals(waterSource.getWaterPressure(), 5);

assertEquals(waterSource.getWaterPressure(), 5);

}

Mocks with Mockito API

Return different values for subsequent calls of the same method.

27/41

Page 28: Mockito   a simple, intuitive mocking framework

www.axon.vn fb.com/AxonActiveVietNam

• The stubbed method is passed as a parameter to a given /

when method.

• So, cannot use this construct for void methods.

• Instead, you should use willXXX..given or doXXX..when

Stubbing void methods

@Test(expectedExceptions = RuntimeException.class)

public void shouldStubVoidMethod() {

doThrow(new RuntimeException()).when(mockedList).clear();

//following throws RuntimeException:

mockedList.clear();

}

Mocks with Mockito API 28/41

Page 29: Mockito   a simple, intuitive mocking framework

www.axon.vn fb.com/AxonActiveVietNam

• Some cases, impossible to test with pure mocks

• Legacy code.

• IoC containers

• "partial mocking" concept

• Instead of mocking, calling directly to real object.

• Usually, there is no reason to spy on real objects

• Code smell

Spying on real objects

Mocks with Mockito API 29/41

Page 30: Mockito   a simple, intuitive mocking framework

www.axon.vn fb.com/AxonActiveVietNam

Example of spying on real objects

List spy = spy(new LinkedList());

when(spy.size()).thenReturn(100); // size() is stubbed.

spy.add("one"); // Assume that this’s legacy code.

assertEquals("one", spy.get(0)); // *real* method

assertEquals(100, spy.size()); // *stubbed* method

//optionally, you can verify

verify(spy).add("one");

Mocks with Mockito API 30/41

Page 31: Mockito   a simple, intuitive mocking framework

www.axon.vn fb.com/AxonActiveVietNam

• Sometimes it's impossible to use when..thenReturn for stubbing

spies.

• Consider doReturn..when

Important gotcha

List spy = spy(new LinkedList());

// the list is yet empty -> IndexOutOfBoundsException

when(spy.get(0)).thenReturn("foo");

//You have to use doReturn() for stubbing

doReturn("foo").when(spy).get(0);

Mocks with Mockito API 31/41

Page 32: Mockito   a simple, intuitive mocking framework

www.axon.vn fb.com/AxonActiveVietNam

• @Mock, @Spy : simplify the process of creating relevant

objects using static methods.

• @InjectMocks : simplifies mock and spy injection

• MockitoJUnit4Runner as a JUnit runner

• Or, MockitoAnnotations.initMocks( testClass )

• Helpful in Spring DI

Annotations

Mocks with Mockito API 32/41

Page 33: Mockito   a simple, intuitive mocking framework

www.axon.vn fb.com/AxonActiveVietNam

public class OrderService {

PriceService priceService;

OrderDao orderDao;

}

@RunWith(MockitoJUnitRunner.class)

public class MockInjectingTest {

@Mock

PriceService mockPriceService;

@Spy

OrderDao spyOrderDao;

@InjectMocks

OrderService testOrderService;

}

Annotations

Mocks with Mockito API 33/41

Page 34: Mockito   a simple, intuitive mocking framework

www.axon.vn fb.com/AxonActiveVietNam

• Verifying exact number of invocations / at least x / never

Some common verifying actions

LinkedList mockedList = mock(LinkedList.class);

mockedList.add("once");

mockedList.add("twice");

mockedList.add("twice");

verify(mockedList, times(1)).add("once");

//exact number of invocations verification

verify(mockedList, times(2)).add("twice");

verify(mockedList, never()).add("never happened");

verify(mockedList, atLeastOnce()).add("twice");

Mocks with Mockito API 34/41

Page 35: Mockito   a simple, intuitive mocking framework

www.axon.vn fb.com/AxonActiveVietNam

Case : how to test ‘cache’ instance ?

@Cacheable CurrencyRequester - getExchangeCurrencyRates() { HttpRequester }

CurrencyRequesterTest

Mocks with Mockito API 35/41

Page 36: Mockito   a simple, intuitive mocking framework

www.axon.vn fb.com/AxonActiveVietNam

HttpRequester mockRequester = mock(HttpRequester.class)

when(httpRequester.makeHttpGetRequest(anyString())).

thenReturn(result);

currencyRequester.getExchangeCurrencyRates();

currencyRequester.getExchangeCurrencyRates();

verify(httpRequester,times(0)).makeHttpGetRequest(anyString());

Mocks with Mockito API

Case : how to test ‘cache’ instance ?

36/41

Page 37: Mockito   a simple, intuitive mocking framework

www.axon.vn fb.com/AxonActiveVietNam

• mock final classes

• mock enums

• mock final methods

• mock static methods

• mock private methods

• mock hashCode() and equals()

Mockito can not :

Limitations

PowerMock or JMockit can be used to work with code that cannot be

mocked with pure Mockito

Mocks with Mockito API 37/41

Page 38: Mockito   a simple, intuitive mocking framework

www.axon.vn fb.com/AxonActiveVietNam

Conclusion

Mockito

Unit testing

Mock framework

mock when..thenReturn

Dependencies

spy ‘partial mocking’

Limitations verify

Argument matchers

Annotations thenThrow

Method stub 1.10.17

Mocks with Mockito API

Write code testable Clean & clear

38/41

Page 39: Mockito   a simple, intuitive mocking framework

www.axon.vn fb.com/AxonActiveVietNam

Unit testing is testing units.

Units bare without dependencies.

And this can be done with mocks

Saying it simply

39/41 Mocks with Mockito API

Page 40: Mockito   a simple, intuitive mocking framework

www.axon.vn fb.com/AxonActiveVietNam

• https://code.google.com/p/mockito/

• http://refcardz.dzone.com/refcardz/mockito

• http://www.slideshare.net/fwendt/using-mockito

References

Mocks with Mockito API 40/41

Page 41: Mockito   a simple, intuitive mocking framework

www.axon.vn fb.com/AxonActiveVietNam

• Try to google “mock test framwork”, “mockito”…

• Visit mockito home page

• Write yourself some code with dependencies, then try to test them

with mock framework.

• Try to find another mock API with your programming language.

• Check out : https://bitbucket.org/phatvu/mockito-learning

• Sample example about Mockito with Java.

• Sample example about Mockito with Spring.

What will you do ?

41/41 Mocks with Mockito API

Page 42: Mockito   a simple, intuitive mocking framework

www.axon.vn fb.com/AxonActiveVietNam Mocks with Mockito API

Page 43: Mockito   a simple, intuitive mocking framework

www.axon.vn fb.com/AxonActiveVietNam Mocks with Mockito API

http://goo.gl/ePWvmA