python unittest.TestCase.assertRaises not working

2019-05-18 16:19发布

I'm trying to run tests on my 'add' function in Python but it is giving an error :

7
E
======================================================================
ERROR: test_upper (__main__.TestStringMethods)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "C:/Users/MaZee/PycharmProjects/andela/asdasd.py", line 22, in test_upper
    self.assertEqual("Input should be a string:", cm.exception.message , "Input is not a string:")
AttributeError: '_AssertRaisesContext' object has no attribute 'exception'

----------------------------------------------------------------------
Ran 1 test in 0.001s

FAILED (errors=1)

Process finished with exit code 1

Here's my code :

    import unittest

    def add(a,b):
        """
        Returns the addition value of a and b.
        """
        try:
          out = a + b
        except TypeError:
          raise TypeError("Input should be a string:")

        print (out)
        return



class TestStringMethods(unittest.TestCase):

    def test_upper(self):
        with self.assertRaises(TypeError) as cm:
           add(3,4)
           self.assertEqual("Input should be a string:", cm.exception.message , "Input is not a string:")


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

1条回答
【Aperson】
2楼-- · 2019-05-18 16:56

As the error message is telling you, your assert raises object has no attribute exception. To be more specific, this call:

cm.exception.message

cm is your assert object in this case, and because the code you are testing never actually raises, your cm object will not have the exception attribute you are trying to access.

Now, on to why this is happening. You are trying to test what happens when an exception is being raised in your add method, in order to raise a TypeError. However, if you look at your test case you are passing two valid integers in to the add method. You will not raise an exception because this is a valid test case.

For your unittest, you are looking to test what happens when you raise something, i.e. insert invalid data to the add method. Try your code again, but this time in your unittest, pass the following:

add(5, 'this will raise')

You will now get your TypeError.

You will also need to perform your assertion validation outside of the context manager:

def test_upper(self):
    with self.assertRaises(TypeError) as cm:
        add(3, 'this will raise')
    self.assertEqual("Input should be a string:", cm.exception.message, "Input is not a string:")

You will now have another problem. There is no message attribute. You should be checking simply cm.exception. Furthermore, in your add method your string is:

"Input should be a string:"

However, you are checking that it is:

"Input is not a string:"

So, once you correct your unittest to use cm.exception, you will now be faced with:

AssertionError: 'Input should be a string:' != TypeError('Input should be a string:',) : Input is not a string:

So, your assertion should check the exception string by calling str on the cm.exception:

self.assertEqual("Input should be a string:", str(cm.exception), "Input should be a string:")

So, your full test method should be:

def test_upper(self):
    with self.assertRaises(TypeError) as cm:
        add(3, 'this will raise')
    self.assertEqual("Input should be a string:", str(cm.exception), "Input should be a string:")
查看更多
登录 后发表回答