Explanation
Failure should be performed in relation to where you are testing, and not where you implemented this method. Or, also in your case, mocking the st object from unittest will not work.
So, I'm not quite sure what the structure of your project is. But hopefully this example helps.
You need to make sure that you also refer to a suitable place where this class is the one you want to make fun of in order to properly mock its methods.
Decision
So let's say you use your tests from test.py:
test.py your_app/ views.py tests/ all_your_tests.py
Inside views.py, you import the submission as follows:
from module_holding_your_class import SendGridClient
So, to look at your mock.patch, it should look like this:
@mock.patch('your_app.views.SendGridClient.send') def test_add_user_page_loads(self, mocked_send):
As you can see, you are working with test.py, so your import is with a link from there. Here I suggest you run your tests as to where you really run your real code so that you don't have to interfere with your import.
In addition, you are mocking the send that you call in views.py.
That should work. Let me know how this happens.
Additional Information: Mocking instance of class
So, based on your code, it would probably be more useful for you if you really mocked an instance of your class. This way, you can very easily test all of your methods within this single layout of your SendGridClient or even Mail instance. That way, you can focus on the explicit behavior of your method without worrying about external functionality.
To mock an instance of a class (or two in your case), you will need to do something like this (inline explanation)
* This specific example has not been verified and is probably not complete. The goal is to make you understand how to manipulate layout and data to help you in testing.
Further below, I have a fully tested example to play with. *
@mock.patch('your_app.views.Mail') @mock.patch('your_app.views.SendGridClient') def test_add_user_page_loads(self, m_sendgridclient, m_mail):
Based on the code you provided, I'm not sure what exactly Mail is returning. I assume this is a Mail object. If so, then the above test case will suffice. However, if you want to check the contents of the message itself and make sure that the data inside each of these object properties is correct, I highly recommend separating your unittests to process it in the Mail class, and make sure the data is as expected.
The idea is that your add_user method add_user not have to worry about validating this data. Itβs just that the call was made with an object.
In addition, inside the sending method itself, you can continue the installation there to make sure that the data you enter into the method is processed accordingly. It will make your life easier.
Example
Here is an example that I put together that I tested, which I hope will help clarify this further. You can copy it to your editor and run. Pay attention to my use of __main__ , this indicates where I am mocking. In this case, it is __main__ .
Also, I would play with side_effect and return_value (look at my examples) to see different behavior between them. side_effect will return something that will be executed. In your case, you want to see what happens when you complete the submit method.
Each unittest mocks in different ways and demonstrates different use cases that you can apply.
import unittest from unittest import mock class Doo(object): def __init__(self, stuff="", other_stuff=""): pass class Boo(object): def d(self): return 'the d' def e(self): return 'the e' class Foo(object): data = "some data" other_data = "other data" def t(self): b = Boo() res = bd() be() return res def do_it(self): s = Stuff('winner') s.did_it(s) def make_a_doo(self): Doo(stuff=self.data, other_stuff=self.other_data) class Stuff(object): def __init__(self, winner): self.winner = winner def did_it(self, a_var): return 'a_var' class TestIt(unittest.TestCase): def setUp(self): self.f = Foo() @mock.patch('__main__.Boo.d') def test_it(self, m_d): ''' note in this test, one of the methods is not mocked. '''