2013-12-12 11 views
5

Tôi đã kéo tóc ra cố gắng tìm ra cách chế tạo lớp sqlite3.Cursor cụ thể là phương pháp fetchall.Làm thế nào tôi có thể thử sqlite3.Cursor

xem xét mẫu mã sau đây

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')) 

Chạy nosetests kết quả trong không có lỗi vui

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) 

Tôi có nên không thể thử phương pháp fetchall hoặc tôi đang làm một cái gì đó khủng khiếp sai?

+1

Xem [Trong Python, làm thế nào để giả lập lớp mở rộng ac?] (Http://stackoverflow.com/q/17267587/222914) –

+1

@JanneKarila Tôi đã thử nhưng bây giờ tôi nhận được một AssertionError https: // gist .github.com/anonymous/7931550: < –

+2

Tôi nghĩ bạn đang vá ở cấp độ sai. Cá nhân tôi muốn vá ra sqlite3 chính nó và giả định phương thức fetch_all như vậy: https://gist.github.com/alexcouper/eec0d38454ce4bc43c6b –

Trả lời

4

Tôi sẽ thực hiện phương pháp vá mã vạch sqlite3 được nhập trong mô đun của bạn và sau đó làm việc từ đó.

Giả sử mô-đun của bạn có tên là what.py.

Tôi sẽ vá what.sqlite3 và sau đó giả lập giá trị trả lại là .connect().cursor().fetchall.

Đây là một ví dụ hoàn chỉnh hơn:

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

Bạn không thể giả lập mọi thứ và cơ sở dữ liệu đặc biệt khó khăn. Tôi thường thấy rằng điều phải làm (đặc biệt là với Sqlite vì nó rất dễ) là tải lên một cơ sở dữ liệu thử nghiệm với dữ liệu giả và sử dụng nó trong các thử nghiệm (ví dụ: đồ đạc). Sau khi tất cả, những gì bạn thực sự cần phải kiểm tra là liệu mã của bạn đang truy cập và truy vấn cơ sở dữ liệu một cách chính xác.

Câu hỏi bạn thường cố gắng trả lời trong thử nghiệm như sau: "Nếu có dữ liệu X trong DB và tôi thực hiện truy vấn Y, truy vấn đó trả về Z như tôi mong đợi", hoặc ở cấp cao hơn " Tôi vượt qua tham số X cho phương pháp của tôi, nó trả về giá trị Z (dựa trên việc nhận Y từ db). "

Trong ví dụ của bạn, câu hỏi thực tế là "Có phải SELECT * FROM foo where name = ? truy vấn đúng trong phương pháp này không?" nhưng bạn không trả lời nếu bạn thử trả lời.

2

Tôi đã tìm thấy một cách để thử sqlite3.Cursor trong các thử nghiệm của tôi:

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

Tôi khá mới trong python nhưng đây là cách tôi làm điều đó trong Java.

Các vấn đề liên quan