learner
learner

Reputation: 959

Reference to same instance in unittest (Not creating new instance when an object is called)

Background: I created a class to extract info from google. This class searches the search term and suggest correction if there is any spelling error with the search term.

class gs:
    url_part1 = "https://www.googleapis.com/customsearch/v1?key="
    key = "some_key"
    cse = 'some_key'
    suggestion = 'None'

def __init__(self, search):
    self.search = search
    self.url = gs.url_part1 + gs.key + gs.cse + self.search
    #gs.suggestion = 'None'

def get_suggestion(self):
    r = requests.get(url=self.url)
    r_json = r.json()
    if 'spelling' in r_json.keys():
        gs.suggestion = r_json.get('spelling').get('correctedQuery')
    return gs.suggestion

For example if I search for paytn (correct name is paytm) then this class suggestion correction for paytn which is paytm

gs_1 = gs(search='paytn')
suggestion_1 = gs_1.get_suggestion()
print(suggestion_1) #suggestion for incorrect name
'paytm'

Instead of searching for paytn if I search for 'paytm' then gs class suggests nothing.

gs_2 = gs(search='paytm')
suggestion_2 = gs_2.get_suggestion()
print(suggestion_2) #no suggestion for correct name
'None'

Now while creating unittest case for gs class I observed a very strange behavior. self.gs_2 is picking up the the values from self.gs_1 and failing the below test.

from search import gs
import unittest

class TestSearch(unittest.TestCase):

    def setUp(self):
        self.gs_1 = gs(search='paytn')
        self.gs_2 = gs(search='paytm')


    def test_get_suggestion(self):
        self.assertEqual(self.gs_1.get_suggestion(), 'paytm')
        self.assertEqual(self.gs_2.get_suggestion(), 'None')


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

Upon inspection it is clear that self.gs_2 is acquiring value from first instance of class gs. Please refer to the output below

import search
suggestion 1 in setUp paytm
suggestion 2 in setUp paytm
F
======================================================================
FAIL: test_get_suggestion (test.TestSearch)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "D:\YBL\test.py", line 15, in test_get_suggestion
    self.assertEqual(self.gs_2.get_suggestion(), 'None')
AssertionError: 'paytm' != 'None'
- paytm
+ None


----------------------------------------------------------------------
Ran 1 test in 3.028s

FAILED (failures=1)

Can anyone help me to understand

1) whether my understanding is correct or not ?

2) Why it is getting values from gs_1 instead of creating a new instance ?

Upvotes: 0

Views: 29

Answers (1)

h4z3
h4z3

Reputation: 5478

class gs:
    url_part1 = "https://www.googleapis.com/customsearch/v1?key="
    key = "some_key"
    cse = 'some_key'

    def __init__(self, search):
        self.search = search
        self.url = gs.url_part1 + gs.key + gs.cse + self.search
        self.suggestion = 'None'

    def get_suggestion(self):
        r = requests.get(url=self.url)
        r_json = r.json()
        if 'spelling' in r_json.keys():
            self.suggestion = r_json.get('spelling').get('correctedQuery')
        return self.suggestion

You used suggestion in gs (same for the whole class), rather than self.suggestion that is instance-specific. You can see it in a way you accessed the value - gs.suggestion means it belongs to gs, self.suggestion means it belongs to the current instance that was passed to the method. ;)

In your case, 1st pass overwrote the gs.suggestion and the 2nd didn't, so it returned the previous value.

Upvotes: 1

Related Questions