2013-12-12 31 views
5

sqlite3.Cursor sınıfını özellikle fetchall yöntemiyle alay etmeyi denemeye çalışıyorum.sqlite3.Cursor'ı nasıl alayım

Ben fetchall yöntemi alay etmek mümkün olmamalıdır hiç eğlenceli hata

E 
====================================================================== 
ERROR: temp.test_foo 
---------------------------------------------------------------------- 
Traceback (most recent call last): 
    File "/home/koddsson/.virtualenvs/temp/lib/python2.7/site-packages/nose/case.py", line 197, in runTest 
    self.test(*self.arg) 
    File "/home/koddsson/.virtualenvs/temp/lib/python2.7/site-packages/mock.py", line 1214, in patched 
    patching.__exit__(*exc_info) 
    File "/home/koddsson/.virtualenvs/temp/lib/python2.7/site-packages/mock.py", line 1379, in __exit__ 
    setattr(self.target, self.attribute, self.temp_original) 
TypeError: can't set attributes of built-in/extension type 'sqlite3.Cursor' 

---------------------------------------------------------------------- 
Ran 1 test in 0.002s 

FAILED (errors=1) 

yılında nosetests sonuçları Running şu kod örneğini

import sqlite3 

from mock import Mock, patch 
from nose.tools import assert_false 


class Foo: 
    def check_name(name): 
     conn = sqlite3.connect('temp.db') 
     c = conn.cursor() 
     c.execute('SELECT * FROM foo where name = ?', name) 
     if len(c.fetchall()) > 0: 
      return True 
     return False 


@patch('sqlite3.Cursor.fetchall', Mock(return_value=['John', 'Bob'])) 
def test_foo(): 
    foo = Foo() 
    assert_false(foo.check_name('Cane')) 

düşünün ya da ben korkunç yanlış bir şey yapıyorum?

+1

[Python'da, ac uzantı sınıfıyla nasıl başa çıkılır?] (Http://stackoverflow.com/q/17267587/222914) –

+1

@JanneKarila Denedim ama şimdi bir AssertionError https: // gist alıyorum .github.com/anonymous/7931550: < –

+2

Sanırım yanlış seviyede yama yapıyorsunuz. Şahsen ben sqlite3 kendini yama ve fetch_all yöntem gibi alay: https://gist.github.com/alexcouper/eec0d38454ce4bc43c6b –

cevap

4

Modülünüzde içe aktarılan sqlite3'ü yamalamak ve daha sonra oradan çalışmayı tercih ederim.

Modülünüzün what.py olarak adlandırıldığını varsayalım.

what.sqlite3 yamalarını çıkarır ve .connect().cursor().fetchall dönüş değerini alayım. Benim testlerde sqlite3.Cursor alay etmek bir yol bulduk

from mock import patch 
from nose.tools import assert_true, assert_false 

from what import Foo 

def test_existing_name(): 
    with patch('what.sqlite3') as mocksql: 
     mocksql.connect().cursor().fetchall.return_value = ['John', 'Bob'] 
     foo = Foo() 
     assert_true(foo.check_name('John')) 
-3

Her şeyle dalga geçemezsiniz ve veritabanları özellikle zor olur. Sık sık yapılması gereken şey (özellikle Sqlite ile çok kolay olduğu için), sahte veri içeren bir test veritabanını yüklemek ve testlerde kullanmak (yani fikstür) kullanmaktır. Sonuç olarak, gerçekten test etmeniz gereken, kodunuzun veritabanına doğru bir şekilde erişip sorulmadığıdır.

Genellikle böyle bir sınamada yanıtlamaya çalıştığınız soru, "DB'de X verileri varsa ve Y sorgusunu yürütürüm, bu sorguyu beklediğim gibi Z döndürür" veya daha yüksek bir düzeyde "Eger X parametresini yöntemime iletirim, Z değerini döndürür (db'den Y'yi almayı temel alır). "

Örneğinizde, asıl soru "Bu yöntemde SELECT * FROM foo where name = ? doğru sorgu mu?" ama cevabını atarsan cevap vermezsin.

2

: Burada

daha eksiksiz bir örnektir

cursor = MagicMock(Cursor) 
cursor.fetchall.return_value = [{'column1': 'hello', 'column2': 'world'}] 

Python oldukça yeni duyuyorum ama bu nasıl Java'da yap.