如何通过从派生类

时间:2017-09-25 17:47:30

标签: django python-2.7 class subclassing class-variables

我正在为我的测试目的开发一个名为dbtest的软件包。这个包是因为我使用MySQLdb连接数据库,因此在测试时编写SQL查询是非常繁琐的任务。所以我创建了一个新包,所有查询都可以通过单独的函数访问。我避免使用django ORM,因为我的数据库表有多个外键和主键。

以下是该套餐的一部分。

package.py

from django.test import TestCase
dbcon='connector'
class testcase(TestCase):
    flag_user=[]

@classmethod                                                               
def setUpClass(cls):

    global dbcon
    dbcon=MySQLdb.connect(host=dbHost,port=dbPort,user=dbUser,passwd=dbPasswd,db=dbname)
    super(testcase, cls).setUpClass()

    cursor = dbcon.cursor()
    sql=open("empty.sql").read()
    cursor.execute(sql)
    cursor.close()

    views.MySQLdb=Mockdb()

@classmethod
def tearDownClass(cls):
   dbcon.close()

def user_table(self,username=username,email=email):

    cache=[username]
    self.flag_user.append(cache)
    cmpdata=(username,email)
    insert_table(tablename_user,cmpdata)

def delete(self,table):
    last_entry=self.flag_user[-1]
    query_user = 'delete from USER where USERNAME=%s'
    cursor=dbcon.cursor()
    query=eval('query_%s'%table)
    cursor.execute(query,last_entry)
    dbcon.commit()
    del self.flag_user[-1]

tests.py

from package import testcase
class showfiles(testcase):

    def setUp(self):
      print "setup2"
      self.user_table(username='vishnu',email='vishnu@clartrum.com')

    def tearDown(self):
      print "teardown2"
      self.delete("user")

    def test_1(self):
      print "test dbtest link feature"


    def test_2(self):
      print "test health/errorfiles with valid device"
      self.user_table(username='vishnu',email='vishnu@clartrum.com')

包中的insert_table在sql中执行insert操作,delete方法删除用户的最后一个条目。 empty.sql为数据库创建表。 实际上,当我运行测试时,最后flag_user应该只包含[['vishnu']]。但是我得到了[['vishnu'],['vishnu']],这是因为拆解中的删除功能并没有更新该值。

我认为这是由于类实例造成的?我是对还是不对?

1 个答案:

答案 0 :(得分:1)

这里:

class testcase(TestCase):
    flag_user=[]

您创建flag_user作为类属性(由所有实例共享)。

然后在这里:

def user_table(self,username=username,email=email):
    cache=[username]
    self.flag_user.append(cache)

您附加到(类级别)flag_user属性(它通过实例访问但它仍然是类属性)

但是在这里:

def delete(self,table):
    delete_table(tablename)
    self.flag_user=[]

在实例本身上创建一个flag_user属性,该属性与eponym类属性完全断开。

最简单的解决方案是从一开始就使用实例属性,而不是使用类属性:

# package.py

from django.test import TestCase
dbcon='connector'

class testcase(TestCase):
    def setUp(self): 
        self.flag_user = []

并且不要忘记在子课程中致电testcase.setUp

# tests.py

from package import testcase
class showfiles(testcase):

    def setUp(self):
      super(showfile, self).setUp()
      self.user_table(username='vishnu',email='vishnu@clartrum.com')

替代解决方案,如果你真的想要一个类属性(我无法想象为什么你会这样做......)是修改testcase.delete(),所以它确实清除flag_user类属性而不是创建实例属性,通过明确要求python重新绑定类本身的属性(type(obj)返回obj.__class__这是实例所属的类):

def delete(self,table):
    delete_table(tablename)
    type(self).flag_user = []