python unittest.TestCase.assertRaises not working
<p>I'm trying to run tests on my 'add' function in Python but it is giving an error :</p>

<pre><code>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
</code></pre>

<p>Here's my code : </p>

<pre><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()
</code></pre>

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

<pre><code>cm.exception.message
</code></pre>

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

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

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

<pre><code>add(5, 'this will raise')
</code></pre>

<p>You will now get your <code>TypeError</code>.</p>

<p>You will also need to perform your assertion validation outside of the context manager: </p>

<pre><code>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:")
</code></pre>

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

<pre><code>"Input should be a string:"
</code></pre>

<p>However, you are checking that it is: </p>

<pre><code>"Input is not a string:"
</code></pre>

<p>So, once you correct your unittest to use <code>cm.exception</code>, you will now be faced with:</p>

<pre><code>AssertionError: 'Input should be a string:' != TypeError('Input should be a string:',) : Input is not a string:
</code></pre>

<p>So, your assertion should check the exception string by calling <code>str</code> on the <code>cm.exception</code>:</p>

<pre><code>self.assertEqual("Input should be a string:", str(cm.exception), "Input should be a string:")
</code></pre>

<p>So, your full test method should be:</p>

<pre><code>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:")
</code></pre>

python pycharm