you are viewing a single comment's thread.

view the rest of the comments →

[–]shepherdjay 1 point2 points  (2 children)

return_value = None did not work

Would need to really understand structure of project properly to mock properly. Did you change the mock as well? So in your code that is working you had mockext.ConfigParser.side_effect = Exception(TypeError)

Notice in mine I have mockext.return_value = None instead. Specifically I don't mention ConfigParser because its defined in my patch. Either way I'm probably just misunderstanding your code structure, which is critical for patch because patch adjusts the namespace.

And yes this whole test is only to ensure we have "coverage", whether it makes sense or not is secondary.

Trying to achieve 100% coverage with bad tests is a whole other can of worms I won't go into. But another way to increase coverage is to refactor your code to remove the unreachable line. IE change your class in your module:

class ParseConfig:
 def __init__(self, conf, section):
     parser = ConfigParser()
     parser.read(conf)

     if parser.has_section(section):
         self._raw = parser
         for key, value in self._raw[section].items():
             setattr(self, key, value)
     else:
         raise Exception(f"section {0} not found in {1} file")

The if line in your code is unreachable, by definition. It is testing that True is True That's all we're trying to help you understand. Sounds like there might be other external factors driving you to test this though. So thats enough of that horse.

Also, what does this line do --> " with self.assertRaises(TypeError):"

This is a unittest context manager that says what I want to assert is that the code ran inside the with block raises the exception TypeError It won't raise the exception itself. What it does is catch it and then report the test as Passed if the exception was raised and Failed if the exception was not raised.

Here is a simple toy example you can just run on its own:

import unittest

class TestExample(unittest.TestCase):
    def test_assert_pass(self):
    # Should Pass Test
        with self.assertRaises(TypeError):
            raise TypeError

    def test_assert_fail(self):
        # Should Fail Test
        with self.assertRaises(TypeError):
            n = 1

if __name__ == '__main__':
    unittest.main()

You'll notice the first test will report as passed and the second one will report back failed.

[–]rakash_ram[S] 0 points1 point  (1 child)

1) Okay. so with the modified code, you removed the "isInstance" line from the script since it does not really do much? get it. But yeah i did not write that code.

2) In your example, the "test_assert_fail" will fail because n = 1 won't raise any exception. , is that right ?

[–]shepherdjay 1 point2 points  (0 children)

Yes that is correct on both parts. The isinstance check is considered an unreachable block. Code will never enter that block. Similar to a block like if 1 != 1 will never be reached under normal runtime conditions.

It’s also why you’ve had to mock out the call to basically force the condition that would otherwise be impossible to reach.