Thread "Automated Testing: Mocking Library"

Tabs

  • Deleted
    Deleted | 22. May 2017, 15:12 Select
    Edited on: 27. Jun 2017, 10:04 - by Deleted
    Automated Testing: Mocking Library

    Hello everyone

    We decided at the Dev-VC that the use of a mocking solution would be a great addition to our current set of tools. Therefore, we need to decide which of the current solutions would be the most suitable for ILIAS.

    I would suggest that each developer who found or already uses an awesome mocking library, writes a short summary about that library. The summary should include a description which emphasize the different abilities, snippets and a reference to the project documentation.

    The voting will start at the 9. June 2017 and end with the final decision at the 26. June 2017.

    Happy testing

    Nick

    Update 7.6.2017: The voting will now start at the 12. June 2017 and the final decision at the 26. June 2017.

    Update 12.6.2017: The poll can be found at http://www.ilias.de/docu/goto_docu_cat_582.html


    Update 27.6.2017:  I am happy to announce the new ILIAS mocking library "Mockery" which won with 86% of the votes. The library has already been added to the trunk.

  • Deleted
    Deleted | 30. May 2017, 10:26 Select
    Mockery

    Introduction

    I would like to introduce mockery which is a simple but yet powerful solution to mock php classes in various ways. Mockery was designed to play nice with PHPUnit and the mocks generated by PHPUnit without breaking everything.

    Mockery supports two main functionalities mocking and spying.

    Mocking allows to generate dynamic test doubles for a given class or interface. It it also possible to generate partial mocks which could come in handy to test legacy code because we could stub all call to old large parent classes. It is also possible to disable the original constructor and verify method invocations with specific parameters. Stubbing static method is also possible if the class is auto loaded and not required (requires can't be intercepted).

    Another feature is to mock hard dependencies (keyword 'new') with the help of the class loading mechanic introduced in PHP 5. This requires running each test in separate processes which is no problem with PHPUnit 5.7. The class which should be mocked must not be loaded before mockery is loading the class or the test fails.

    Spying on the other hand is only used to observe objects, which could be useful in some cases to verify specific interactions with an object.

    Code Snippets

    Simple example:

    This example shows a simple example how mockery is used to test the class "Temperature". The close call on the Mockery class is required to trigger the evaluation of the assertions defined on the mock object service. There is also a trait which does the same thing.

    Code:

    Mockery simple example

    Test:

    Mockery simple example test code

    Example Legacy test:

    There are a lot of classes which extends big classes which are responsible for a lot of stuff. The problem is that we would test our class and probably half of the parent class which is not a desirable thing. To work around the parent class, we need to create a partial mock of the test subject "ChildClass" and stub only the methods of the parent class.

    Code:

    Mockery legacy code

    Test:

    Mockery legacy test

    The above examples are from the Mockery documentation.

    Mockery documentation: http://docs.mockery.io/en/latest/index.html

    Side note

    I tested Mockery with PHPUnit 4.8, 5.7 and 6.1. It worked with all versions. The only problem I encountered so far was the MockeryTestCase class is not compatible with PHPUnit 6 due to the renamed test case class. There is simple work around, Mockery also provides a trait which does the same thing as the MockeryTestCase class.

    The release 1.0 will most likely be released this year.

    Caveats

    It seems like there is no possibility to mock methods which returning a generator according to issue 520.

  • rklees
    Richard Klees | rklees | 9. Jun 2017, 11:12 Select
    Mockery

    Hi Nick,

    could you comment a little on the benefits that mockery provides over the default mocking framework of PHPUnit? To me this will be a very important question for the poll.

    Best regards!

  • Deleted
    Deleted | 11. Jun 2017, 23:00 Select
    Mockery

    Hi Richard that is a good idea,

    I think the main difference between the PHP mock functionality and mockery is the fact that mockery focus on the creation and validation of mocks in various way were PHP unit has a stronger focus towards a general toolkit.

    Focus Mockery:

    • Validation of function calls on mock objects before and after the actual calls.
    • Support to mock hard dependencies (new keyword) which is good to test the old parts of ILIAS.
    • Object spy capability for method call verification with real objects.
    • Alias creation to mock static calls.

    Focus PHP Unit:

    • Creation of stubs
    • Creation of mocks for method call verification.

    To sum up, the build in mocking solution of PHP Unit has a solid kit which allows to test the newly written code in hardly any case. The kit has also some limitations like no support for mocking static calls and hard dependencies. 

    Mockery in contrast provides a more powerful set which enables the developers to intercept the creation of objects or loading of classes to test static method calls. The capabilities are powerful but could also be misused in the future.

    Please note that I am more experienced with mockery. Corrections additions and notes from other developers are highly appreciated!

     

  • amstutz
    Timon Amstutz | amstutz | 12. Jun 2017, 14:26 Select
    Mockery
    Thanks Nicolas for your insight, initiative and information on this! That was really helpful. Unfortunately, I am not expert on mocking libraries at all. However, from the information provided by Nicolas it seems, that Mockery seems better suited to write tests for code including old nasty dependencies (which is almost always the case with ILIAS). So my vote goes for mockery.
  • shecken
    Stefan Hecken | shecken | 8. Jun 2017, 11:23 Select
    Test Doubles with PHPUnit

    The mocking solution of PHPUnit has a huge amount of options. But the usage is very simple.

    To get a stub of an class or interface PHPUnit offers two possibilities. A very short with preconfigured steps and a bit longer where the user is allowed to decide which steps should be performed if a stub is created.

    Let‘s have a look on examples.

    Example class:

    test_class.png

    Test 1:

    In this test we are using the fast version of creating a mock. For this we only have to call "createMock". After that the stub will immediately be created withour calling __construct or __clone. We want to configure the stub in the way that getValue returns a simple value.

    test1.png

    Test 2:

    Now we will use the morge configurable version of creating a stub. For this we first have to create a MockBuilder. After that there is are a pool of configuration functions.
    We want to prevent that the __construct and __clone will be called. Now we can get the Stub via "getMock".
    In this test we double the second method (addTwo) of test class, to show how to define arguments.

    test2.png

    For the complete documention please click.