Starting from:

$25

TQS - Lab 2  Mocking dependencies -Solved

unit testing
Context and key points
Learning objectives
⎯ Prepare a project to run unit tests (JUnit 5) and mocks (Mockito 3.x), with mocks injection (@Mock).

⎯ Write and execute unit tests with mocked dependencies.

⎯ Experiment with mock behaviors: strict/lenient verifications, advanced verifications, etc.

Preparation 

Get familiar with sections 1 to 3 in the Mockito (Javadoc) documentation.  

Explore
-     There is a recent book on JUnit and Mockito available from OReilly. The lessons are available as short videos too.

2.1  Stocks
Consider the example in Figure 1: the StocksPortfolio holds a collection of Stocks; the current value of the portfolio depends on the current condition of the Stock Market.  StockPortfolio#getTotalValue() method calculates the value of the portfolio (by summing the current value of owned stock, looked up in the stock market service).  

 

1a/ 

Implement (at least) one test to verify the implementation of StockPortfolio#getTotalValue().  Given that test should have predictable results, you need to address the problem of having nondeterministic answers from the IStockmarketService interface.

 

  Figure 1: Classes for the StocksPortfolio use case. 

a)    Create the classes. You may write the implementation of the services before or after the tests.  

b)    Create the test for the getTotalValue(). As a guideline, you may adopt this outline:

1.       Prepare a mock to substitute the remote service (@Mock annotation) 

2.       Create an instance of the subject under test (SuT) and use the mock to set the (remote) service instance. 

3.       Load the mock with the proper expectations (when...thenReturn) 

4.       Execute the test (use the service in the SuT) 

5.       Verify the result (assert) and the use of the mock (verify) 

 

Notes:

⎯ Consider use these Maven dependencies for your POM (JUnit5, Mockito).

⎯ Mind the JUnit version. For JUnit 5, you should use the @ExtendWith annotation to integrate the Mockito framework.

@ExtendWith(MockitoExtension.class) class StocksPortfolioTest { … } 

⎯ See a quick reference of Mockito syntax and operations.

 

1b/ Instead of the JUnit core asserts, you may use the Hamcrest library to create more humanreadable assertions. Replace the “Assert” statements in the previous example, to use Hamcrest constructs. E.g.:

assertThat(result, is(14.0)); 

2.2 Geocoding
Consider an application that needs to perform reverse geocoding to find a zip code for a given set of GPS coordinates. This service can be assisted by public APIs (e.g.: using the MapQuest API).  

Let as create a very simple application to perform (reverse) geocoding and set a few tests.

a)    Create the objects represented in Figure 1. At this point, do not implement TqsBasicHttpClient; in fact, you should provide a substitute for it.

b)    Consider that we want to test the behavior of AddressResolver#findAddressForLocation, which invokes a remote geocoding service, available in a REST interface, passing the site coordinates.  Which is the SuT (subject under test)? Which is the service to mock?  

c)     To create a test for findAddressForLocation, you will need to mimic the exact (JSON) response of the geocoding service for a request. Study/try the MapQuest API (e.g.: example 1).

d)    Implement a test for AddressResolver#findAddressForLocation (using a mock).

e)    Besides the “success” case, consider also testing for alternatives (e.g.: bad coordinates;…). You may need to change the implementation.

This getting started project [gs-mockForHttpClient] can be used in your implementation.

 

  

Figure 2: Classes for the geocoding use case. 

2.3 Integration
Consider you are implementing an integration test for the previous example, and, in this case, you would use the real implementation of the module, not the mocks, in the test.

(This section can be included with the previous, continuing the same project.)

 

Create a test class (AddressResolverIT), in a separate test package, and be sure its name ends with “IT”. Copy the tests from the previous exercise into this new test class but remove any support for mocking (no Mockito imports in this test).  

Correct/complete the test implementation so it uses the real HttpClient implementation.  Run your test (and confirm that the remote API is invoked in the test execution).  

 

Be sure the “failsafe” maven plugin is configured. You should get different results with:

$ mvn test and 

$ mvn install failsafe:integration-test 

(Note the number of tests and the time required to run the tests…).

More products