Logbook - page 4

  • Pitfalls with mocking in Python

    Yesterday I have implemented a test for a Python module of the efaLive project. It required me to mock out one class that is used by the test target. So I used the @patch annotation to mock the class. In a first step I used assert_called_once(), copied from some website, to verify that a specific method of the mock has been called. The test was green. Then I changed the test to use assert_called_once_with() to verify the arguments of the mock method as well. After that, the test became red. I checked the test code and did not find the reason for this. With assert_called_once() I verified that the method is called, but assert_called_once_with() tells me that it is called with other arguments than I expected. Here the test code that was green:

    1
    2
    3
    4
    5
    
    @patch("package1.ThirdPartyClass")
    def test_my_module(self, third_party_mock)
        class_under_test = my_module.MyClass()
        class_under_test.do_something()
        third_party_mock.called_by_do_something.assert_called_once()
    

    After a while I found an interesting article about this problem. The point is: third_party_mock is a mock object and in Python you can call any method of such a mock and it will not fail. The method assert_called_once() does not exist. It was a failure to copy this code from an article in the web. However, the method assert_called_once_with() exists and triggers the statistics of the mock object. But there is another problem in the test code. The method called_by_do_something() is never called of the mock, but of its instance. So the correct code would be:

    1
    2
    3
    4
    5
    
    @patch("package1.ThirdPartyClass")
    def test_my_module(self, third_party_mock)
        class_under_test = my_module.MyClas()
        class_under_test.do_something()
        third_party_mock.return_value.called_by_do_something.assert_called_once_with("foo")
    

    This code will work and trigger the correct mock statistics. To avoid issues like this, I even go a step further now. I don’t use the convenience method assert_called_once_with() any more. Now I use the statistics attributes call_count and call_args directly. Here is what I would suggest to use for the test:

    1
    2
    3
    4
    5
    6
    
    @patch("package1.ThirdPartyClass")
    def test_my_module(self, third_party_mock)
        class_under_test = my_module.MyClas()
        class_under_test.do_something()
        self.assertEqual(1, third_party_mock.return_value.called_by_do_something.call_count)
        self.assertEqual(call("foo"), third_party_mock.return_value.called_by_do_something.call_args)
    
  • efaLive 2.3 released

    I now have uploaded efaLive 2.3 to the server. The main difference is that this version is now based on the new stable Debian release “Jessie” 8.0. Besides that there is a small watchdog that restarts the PC in case of a X-server crash. For more details have a look to the efaLive page.

    Unfortunately the image size has grown over 700 MB. So you can not burn the image to a standard CD. You need an oversize CD oder a DVD. However, I recommend to use a USB stick, anyway.

  • Web pages update

    I have updated my web pages, the layout and the CMS, as you might have recognized already. The layout works responsive now. This was one of my main goals. Besides that I simplified the layout so that there are less graphics. This hopefully reduces the page load and loading time. So the pages should be ready for the mobile world. The only part that does not work responsive completely is the gallery. The details view does not resize. I hope that I will find a solution for that. The content is more or less the same as before.

    Now have fun on the pages!

  • efaLive 2.2 released

    Today I have released efaLive version 2.2. There are many structural changes but some new features as well. For more information check the efaLive page.

  • Microsoft's hand made parser

    I recently had to implement an API to send push messages to Windows phone 8 from Java. So called “tile” messages did work fine after getting the authentication part working. But “toast” messages did not work. The Microsoft push server answered that everything is OK, but the test software on the phone said that there is an error in the payload. The payload for these messages is XML which describes to the phone what text etc it should display.

    After some conversation with Microsoft everything pointed to the encoding of the XML payload. I was wondering, why they use different encoding for tile and toast messages. After some checks in the code, I was 100% sure that I send UTF8 there as required.

    Then I took a test push send software from Microsoft and analyzed the payload. There were some different HTTP headers, but the payload was XML just as mine. The only difference was, that the Microsoft payload was formatted XML. And yes, unbelievable, but this was the problem. After I added carriage return/line feed and some spaces, the toast messages worked as expected.

    Thanks Microsoft for this nice hand made XML parser that expects the payload to contain “\r\n” to form a well formatted XML string!! And I thought that formatting XML is only good for human being’s eyes. You never stop learning…

subscribe via RSS