#######################
Considerations on Tests
#######################

*Note: This document is a work in progress.*

PowerMock
=========

Avoid using PowerMock, if you can at all. It is black magic with special
class loaders to mock static and what not really is a band aid for
existing legacy code impossible to test. Consider refactoring the respective
OpenDaylight code to be tested first, if you can.

Also think twice if you're using PowerMock on existing utility classes -
you may be testing at the wrong level. For example, many projects have
utilities that deals with the DataBroker (that's wrong, common shared
utilities should be used). Many of these utility classes have static
methods (that's wrong, they should get a DataBroker passed to their
constructor, see
``org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker``,
imagine there is no static there, that's again just for legacy). When
writing a test, you could be tempted to use PowerMock on such static
utility methods. That's wrong though - you should just let the code
under test use such utilities - and use a test implementation of the
DataBroker.

DataBroker
==========

Typically you probably should not be mocking the DataBroker (using
whatever framework), because there is a reasonably light weight test
implementation of the entire persistence subsystem that is well suited
for use in tests. You can easily use it by having your \*Test class
extends
``org.opendaylight.controller.md.sal.binding.test.ConstantSchemaAbstractDataBrokerTest``
and calling ``getDataBroker()``, or just using the
``org.opendaylight.controller.md.sal.binding.test.DataBrokerTestModule``
static ``dataBroker()`` method.

NB that if you use the above, then (obviously) it makes no sense
(anymore) to use ``@RunWith(MockitoJUnitRunner.class)`` and ``@Mock DataBroker``
and the transactions.

Mockito
=======

Using Mockito can be fine - but keep an eye on how lines in your test
are pure "Mockito infrastructure" related VS how many are "actually
really test code". Do not "over-mock"; for example, there is absolutely
no point in mocking implementations of the interfaces YANG code
generations used e.g. for RPC input & output objects - just use the
\*Builder, like "real" code would. Also of course you would never Mock
something like e.g. a Future or an Optional (seen in existing ODL
code!).

Use "normal" Java, with a hint of Mockito
=========================================

Be careful not to overstretch usage of Mockito and write complicated to
read many lines of Mockito to set up a series of Mock objects if you
could achieve the same relatively simply using standard Java, perhaps
using a simple anonymous inner class. For example, the following is
perfectly fine to do something like this in a test, and probably more
readable to most people looking at your test than the equivalent in
Mockito:

.. code:: java

   YourRpcService testYourRpcService = new YourRpcService() {
       @Override Future<RpcResult<Output>> someOperation(Input input) {
           if ( ... input some condition ...) {
               return Futures.immediateFailedFuture(RpcResultBuilder.failed());
           }
       };
       ...
   }

If ``YourRpcService`` has other methods than just ``someOperation()``, you can
use a variant of "partial mocking":

.. code:: java

   import static org.opendaylight.yangtools.testutils.mockito.MoreAnswers.realOrException;

   YourRpcService testYourRpcService = Mockito.mock(new YourRpcService() {
       @Override Future<RpcResult<Output>> someOperation(Input input) {
           if ( ... input some condition ...) {
               return Futures.immediateFailedFuture(RpcResultBuilder.failed());
           }
       }, realOrException());
       ...
   }


Test Implementations of commonly used services
==============================================

If several tests, or even other modules, are likely to use a stubbed
service, then (only) it is worth to write something re-usable like this:

.. code:: java

   class abstract TestYourRpcService implements YourRpcService {
       public static YourRpcService newInstance() {
           return Mockito.mock(TestYourRpcService.class, realOrException());
       }
       @Override Future<RpcResult<Output>> someOperation(Input input) {
           ...
       }
       ...
   }


Asserting Object structures
===========================

To assert the expected state of a tree of objects, typically but not
necessarily data objects in Java objects generated by YANG binding, a
number of projects use the `vorburger/xtendbeans
library <https://github.com/vorburger/xtendbeans>`__.

The ``org.opendaylight.mdsal.binding.testutils.AssertDataObjects`` provides
tight integration of this into OpenDaylight, including the
``org.opendaylight.mdsal.binding.testutils.XtendBuilderExtensions``, which
makes for a very readable syntax.

Component Tests
===============

It's not that hard to write Component Tests which test the interaction
of a number of interrelated services, without going to a full blown and
much "heavier" Karaf OSGi integration test just yet; see :ref:`component`.

Integration Tests
=================

Use `Integration Tests (IT) to get a full Karaf OSGi runtime
environment <https://wiki-archive.opendaylight.org/view/CrossProject:HouseKeeping_Best_Practices_Group:Integration_Test>`__.
*TODO Simplify that...*

Recommended Reading
===================

-  https://googletesting.blogspot.ch/2013/07/testing-on-toilet-know-your-test-doubles.html
-  https://martinfowler.com/articles/mocksArentStubs.html