2011-11-10 5 views
12

Tôi có một thư viện Java sử dụng một vài thứ từ API Android. Tôi muốn sử dụng Mockito để viết các bài kiểm tra đơn vị cho thư viện này.Android: Đơn vị kiểm tra các ứng dụng Android với Robolectric và Mockito

Có cách nào tôi có thể thực hiện việc này không?

Mockito không chơi đẹp trên Dalvik VM, xem bài này: Using Mockito with Android virtual machine

UPDATE:

Kể từ bài này, tôi đã phát hiện ra Robolectric, và tôi đã có cơ hội để làm việc trong số các Lab của Pivotal và đóng góp một phần nhỏ vào thư viện này. Tôi khuyên bạn nên sử dụng tính năng này trên khung kiểm tra Android/mockito. Ngoài ra, bạn được tự do sử dụng Robolectric AND Mockito, nhưng các đối tượng bóng trong Robolectric làm cho Mockito không cần thiết cho hầu hết các trường hợp sử dụng.

Vấn đề với việc thử nghiệm đơn vị Android là thư viện Android mà bạn xây dựng trên mọi phương thức đều được đưa ra để ném một ngoại lệ stub hoặc trả về null. Nếu bạn muốn thử nghiệm ứng dụng của mình và muốn bất kỳ hành vi Android nào bạn không may mắn, trừ khi bạn sử dụng Robolectric để viết lại mã byte khi các lớp tải và tiêm đối tượng bóng mô phỏng hành vi.

UPDATE 2:

Nó được một lúc và mọi thứ đã thay đổi. Nhiều lớp Shadow trong Robolectric đã được thay thế bằng các lớp Android thực sự. Các lọ thực sự của Android hiện đang được sử dụng và Robolectric chỉ tải các lớp Shadow cho một tập hợp nhỏ hơn nhiều. Điều này thậm chí còn nhiều hơn một lý do để sử dụng Robolectric cho thử nghiệm Android của bạn.

Trả lời

9

Sau nhiều Googling, tôi đã xem câu trả lời cho số here này.

Về cơ bản nó liên quan đến việc sử dụng khung kiểm tra đơn vị Robolectric, ngăn chặn việc tải các lớp học Android. Sau đó bạn có thể tiếp tục và sử dụng Mockito (mặc dù nó không cần thiết trong hầu hết các trường hợp) và chạy thử nghiệm của bạn trên JVM!

+0

Tôi sử dụng Spy-xây dựng từ Mockito kết hợp với các nhà xây dựng được cung cấp bởi Robolectric. Bằng cách đó tôi có thể làm một phần chế nhạo các thành phần Android khi cần thiết, ví dụ: FooActivity foo = spy (Robolectric.buildActivity (FooActivity.class) .get()); doReturn (mock) .when (foo) .getSomething(); – Alix

1

Hãy xem android-mock. Nó dựa trên EasyMock 2.4 (vì vậy không hoàn toàn đẹp như Mockito nhưng đóng).

Nó được xung quanh các giới hạn của DalvikVM bằng cách tạo trước các lớp mô phỏng tại thời gian xây dựng chứ không phải là thời gian chạy, sau đó kết hợp chúng với mã thử nghiệm đã biên dịch của bạn khi triển khai thiết bị.

Ngoài ra còn có một khung mocking được gọi là Borachio mà tôi không thể xác minh nhưng có vẻ đầy hứa hẹn (nếu bạn sẵn sàng trải qua các chuyển động để Scala chạy trên thiết bị của bạn).

+0

Yeah, tôi biết về điều đó. Tôi đang cố gắng tránh sử dụng nó nếu tôi không phải làm vậy. Cú pháp trên Mockito đẹp hơn rất nhiều. –

1

Bạn có thể tránh điều đó, vì mọi thứ không liên quan gì đến các lớp nội bộ của Android SDK. Đó là những gì tôi đang làm cho các dự án Android của mình (mặc dù tôi sử dụng JMock2, không phải Mockito).

Tôi có hai dự án thử nghiệm.

  • Người đầu tiên sử dụng JUnit4JMock2 mà tôi thêm vào bản thân mình như phụ thuộc. Tôi kiểm tra tất cả các lớp "logic nghiệp vụ", nhưng tôi không thể kiểm tra bất cứ thứ gì phải làm với Android (lớp UI, SQLiteOpenHelper, v.v.) Nếu tôi cố gắng sử dụng chúng trong các bài kiểm tra của mình, tôi nhận được ngoại lệ đáng sợ Stub!.

  • Cách thứ hai để kiểm tra giao diện người dùng, sử dụng ActivityInstrumentationTestCase2Robotium.

Điều đó có vẻ như rất nhiều công việc và phức tạp, nhưng thực sự không, và tôi thực sự nghĩ tốt hơn là tách chúng ra.Kiểm tra giao diện người dùng không phải là các thử nghiệm đơn vị "thực" và họ thường kiểm tra một số tính năng trên nhiều đơn vị. Nếu bạn tách riêng lớp UI khỏi logic nghiệp vụ của bạn (và thực hiện việc tách kiểm tra này sẽ buộc bạn phải làm điều đó, theo kiểu TDD), thì tất cả đều tốt đẹp và mượt mà.

+0

Thở dài. Vấn đề là các lớp mô hình kinh doanh của tôi sử dụng AsyncTask để lấy tất cả các dữ liệu tôi đang sử dụng trong ứng dụng, trên mọi trang. Tôi đã suy nghĩ, vì AsyncTask về cơ bản là một POJO mà tôi chỉ có thể lấy mã cho nó và đặt nó vào dự án của tôi và mất sự phụ thuộc. –

+0

Nếu tôi là bạn, tôi sẽ cố gắng để trừu tượng ra tất cả các phụ thuộc Android để giao diện, để các Stub không nhận được trong cách. Có lẽ không phải là dễ dàng như nó âm thanh với AsyncTask mặc dù ... – Guillaume

+0

@Chirstopher Perry: Bạn đã nhận được một số giải pháp của vấn đề của bạn để kiểm tra ASync Tasks hiệu quả? Bây giờ tôi đang ở trong cùng một chiếc thuyền. – bianca

2

Kể từ phiên bản 1.9.5 (phát hành ngày 3 tháng 6 năm 2012), bạn có thể sử dụng Mockito với Android. Để làm điều này bạn cũng sẽ yêu cầu dexmaker:

trang

http://code.google.com/p/dexmaker/

wiki này mô tả làm thế nào để thực hiện nó:

http://code.google.com/p/dexmaker/wiki/Mockito

+0

Điều này không cung cấp cho bạn bất kỳ hành vi Android nào. Robolectric vẫn là lựa chọn tốt nhất, vì nó cung cấp Mocks (các lớp bóng) và hành vi Android. –

+2

Tôi hiểu, nhưng câu hỏi của bạn không phải là 'khung mocking tốt nhất cho Android' nhưng 'làm cách nào tôi có thể sử dụng Mockito với Android'. –

+0

@ChristopherPerry Tôi nghĩ rằng có thể có một số nhầm lẫn thực sự. Sử dụng Mockito theo cách này với khung kiểm tra Android và JUnit có nghĩa là các thử nghiệm của bạn chạy trên thiết bị thực hoặc trình giả lập, nghĩa là tất cả các lớp Android đều khả dụng. Khung kiểm tra Android cũng cung cấp các mock được xây dựng, chẳng hạn như 'MockContext'. –