Cách chế nhạo người dùng và yêu cầu trong django


75

Tôi có mã django tương tác với các đối tượng yêu cầu hoặc đối tượng người dùng. Ví dụ như:

foo_model_instance = models.get_or_create_foo_from_user(request.user)

Nếu bạn định thử nghiệm với vỏ trăn django hoặc trong một vật thể độc nhất, bạn sẽ vượt qua được thứ gì trong đó? Ở đây chỉ đơn giản là một đối tượng Người dùng sẽ làm, nhưng nhu cầu về một đối tượng yêu cầu giả cũng xuất hiện thường xuyên.

Đối với shell hoặc unittest:

  • Làm thế nào để bạn chế nhạo người dùng?
  • Làm thế nào để bạn mô phỏng các yêu cầu?

2
"Bạn tiếp tục sử dụng từ đó, nhưng tôi không nghĩ nó có nghĩa như những gì bạn nghĩ nó có nghĩa là ..." Tôi nghĩ bạn có nghĩa là "giả lập".
Mike DeSimone

9
@Mike: Nghe có vẻ buồn cười, nhưng tôi nghĩ anh ấy nói đúng. @pax: Đánh bại tôi trước đường đột :(
mpen

6
Tôi ... tôi phải thú nhận rằng ... trong sự im lặng của căn phòng của tôi ... vào đêm khuya ... tôi ... vâng, vâng! Tôi chế nhạo người dùng! Tất cả bọn họ! @perrierism: chúng tôi không chế nhạo bạn, chúng tôi chỉ tận hưởng sự lựa chọn từ ngữ tuyệt vời của bạn.
Peter Rowell

Câu trả lời:


84

Đối với yêu cầu, tôi sẽ sử dụng RequestFactory đi kèm với Django.

from django.test.client import RequestFactory
rf = RequestFactory()
get_request = rf.get('/hello/')
post_request = rf.post('/submit/', {'foo': 'bar'})

đối với người dùng, tôi sẽ sử dụng django.contrib.auth.models.User như @ozan đề xuất và có thể với factory boy để có tốc độ (với factory boy, bạn có thể chọn không lưu vào DB)


1
Đây chắc chắn là câu trả lời chính xác khi hiện có RequestFactory. Với câu trả lời của Ozan (việc tạo ra các đối tượng thực là đủ và đáng mơ ước). Tôi chưa sử dụng Factory Boy nhưng nếu nó gần với chất lượng của Rail's Factory Girl thì có vẻ nó sẽ là một lựa chọn tuyệt vời.
Purrell

Giải pháp tốt nhất phù hợp với tôi trong tập lệnh di chuyển django. Tuy nhiên phiên bản hiện tại yêu cầu request.userphải được thiết lập. Cũng sử dụng yêu cầu này như một cái nhìn bình thường nó là tốt đẹp để có request.csrf_processing_done = Truetrong yêu cầu sẵn sàng (để vượt qua kiểm tra CSRF)
garmoncheg

51

Làm thế nào để bạn chế nhạo người dùng?

Khởi tạo một django.contrib.auth.models.Userđối tượng. User.objects.create_userlàm cho điều này dễ dàng.

Làm thế nào để bạn mô phỏng các yêu cầu?

Khởi tạo một django.http.HttpRequest đối tượng.

Tất nhiên, có những phím tắt tùy thuộc vào những gì bạn muốn làm. Nếu bạn chỉ cần một đối tượng có userthuộc tính trỏ đến người dùng, chỉ cần tạo một cái gì đó (bất cứ thứ gì) và cung cấp cho nó thuộc tính đó.


2
@ S.Lott đôi khi sử dụng đồ thật thì rất tốt nhưng kết thúc rất chậm khi dự án của bạn phát triển. Thật tuyệt khi có các bài kiểm tra thử bạn có thể chạy trong vài giây thay vì vài phút.
TM.

1
@TM: Có lẽ điều này nói chung đúng. Nhưng ứng dụng Django thực sự rất nhanh. Bạn có một số thay thế và một số điểm chuẩn để hiển thị thời gian tiết kiệm không?
S.Lott

@ S.Lott chỉ cần trải nghiệm với các dự án của riêng tôi. Thay thế cho việc sử dụng người dùng tích hợp chỉ là sử dụng thứ gì đó như khung công tác pymox hoặc tạo các đối tượng giả của riêng bạn với cùng một API như đã được đề xuất trong một số câu trả lời ở đây. Sử dụng các đối tượng yêu cầu thực không phải là vấn đề tốc độ.
TM.

11
@ S.Lott Tôi không nói rằng ứng dụng khách chậm, hoặc tuyên bố chế độ giả nhanh hơn ứng dụng khách (Tôi giả định rằng bởi "khách hàng" bạn đang đề cập đến "trình duyệt" web giả djangos). Tôi đang nói rằng chúng nhanh hơn truy cập DB (chỉ áp dụng cho Userphần của câu hỏi này). Nếu bạn không nghĩ rằng các trò giả nhanh hơn thực sự truy cập vào DB, thì tôi nghi ngờ rằng bạn chưa thực sự thử và so sánh. Trong một dự án rất nhỏ, nhóm của chúng tôi đã đi từ bộ thử nghiệm mất 1,5 phút xuống <5 giây khi chúng tôi thay đổi mã để mô phỏng các mô hình. Không cần thiết phải viết điểm chuẩn khi khoảng cách quá lớn.
TM.

1
Yêu cầu thực sự của tôi có một .userthuộc tính. Các trường hợp của django.http.HttpRequestkhông. Tôi chỉ thiết lập request.user sau khi tạo nó. Điều đó có vẻ hợp lý?
Jonathan Hartley

7

Bạn có thể tạo ra các chế độ giả của riêng mình, như Anurag Uniyal đã đề xuất hoặc bạn có thể sử dụng một khuôn khổ chế tạo.

Đáp lại những người nói rằng bạn chỉ có thể tạo một người dùng bình thường như bạn vẫn làm trong Django ... Tôi khuyên bạn nên điều này đánh bại điểm của bài kiểm tra đơn vị. Một bài kiểm tra đơn vị không nên chạm vào cơ sở dữ liệu, nhưng bằng cách tạo người dùng, bạn đã thay đổi cơ sở dữ liệu, do đó tại sao chúng tôi muốn mô phỏng một bài kiểm tra.


2
Như Daniel đã đề cập, trình chạy thử nghiệm tạo sau đó phá hủy cơ sở dữ liệu thử nghiệm cho bạn, vì vậy bạn không cần phải lo lắng về điều đó.
ozan

4
Ngoại trừ nếu bạn đang sử dụng cơ sở dữ liệu, thì đó không phải là một bài kiểm tra đơn vị nữa. Nó vẫn có thể là một bài kiểm tra tích hợp hoàn toàn hợp lệ, nhưng nó không phải là một bài kiểm tra đơn vị.
Michael Williamson

1
Vấn đề là việc tạo và hủy một cơ sở dữ liệu cần nhiều thời gian. Cuối cùng tôi muốn chạy hàng nghìn bài kiểm tra trong chớp mắt, mỗi khi tôi thực hiện thay đổi. Tôi không muốn tạo một cơ sở dữ liệu và một phiên bản ứng dụng để chạy các bài kiểm tra của mình.
Tim Ottinger

Đồng ý, sẽ rất hữu ích khi có các bài kiểm tra không đạt được DB. Ngay cả khi bạn đang sử dụng cơ sở dữ liệu SQLite, nó vẫn chậm hơn so với các bài kiểm tra sử dụng mocks.
TM.

6

Đọc về các đối tượng giả tại đây
http://en.wikipedia.org/wiki/Mock_object
http://www.mockobjects.com/

Và sử dụng python lib này để chế nhạo người dùng
http://python-mock.sourceforge.net/

nếu không, bạn có thể tự viết một lớp Người dùng đơn giản, sử dụng lớp này làm điểm bắt đầu

class MockUser(object):
    def __call__(self, *args, **kwargs):
        return self

    def __getattr__(Self, name):
        return self

thêm các trường hợp cụ thể, v.v.


5

Bạn không cần phải chế nhạo Người dùng, vì bạn chỉ có thể tạo một người dùng trong thử nghiệm của mình - cơ sở dữ liệu sẽ bị phá hủy sau khi thử nghiệm kết thúc.

Để mô phỏng các yêu cầu, hãy sử dụng đoạn mã này từ Simon Willison.


Mặc dù tôi đồng ý rằng bạn thường có thể thoát khỏi việc tạo Người dùng cho bạn thử nghiệm - đôi khi bạn không muốn - hoặc làm như vậy nằm ngoài thời gian thực hiện thử nghiệm. Nếu tôi đang thử nghiệm thì quyền đó bị từ chối nếu một phương thức trợ giúp trả về False - tôi sẽ sai khi ghép nối điều đó với cơ sở dữ liệu. Phương thức trợ giúp đó tồn tại VÌ tôi không muốn biết về cách biểu diễn cơ sở dữ liệu.
yarbelk
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.