2011-08-09 43 views
13

Tôi hiện đang nghĩ đến "Cách thiết kế thành phần OSGi để dễ dàng viết các thử nghiệm cho nó với các khung như jUnit và Mockito".Unit-Testing OSGi-Components

Giả lập liên bó-phụ thuộc khá dễ dàng vì OSGi tăng cường DIP (Nguyên tắc đảo ngược phụ thuộc) và phương pháp phun (ví dụ: setter) thường tồn tại.
Nhưng còn phụ thuộc vào gói nội bộ thì sao?

Ví dụ: xem this case. Bây giờ tôi muốn đưa nó vào một bối cảnh OSGi ... Hình ảnh chúng tôi muốn cung cấp bất kỳ loại giao thức mạng nào như một dịch vụ khai báo trong nền tảng OSGi và muốn viết các bài kiểm tra đơn vị để kiểm tra mã mạng thấp hơn tương tác trực tiếp với đối tượng socket.

Nếu chúng ta sẽ cấu trúc lại việc tạo ổ cắm thành một gói POJO bên trong (Lớp Java cũ đơn giản), thì chúng ta nên tiêm nó vào thực hiện giao thức như thế nào?

  • Trong thử nghiệm đơn vị, chúng tôi có thể sử dụng phương pháp setter đơn giản nhưng ai sẽ làm điều này trong vùng chứa OSGi cho chúng tôi?
  • Phân lớp lớp được kiểm tra và ghi đè phương thức của người sáng tạo sẽ chỉ hoạt động nếu lớp được kiểm tra không được khai báo là cuối cùng.

Trả lời

8

Kiểm tra tương tác với vùng chứa OSGi, nói đúng, kiểm tra tích hợp. Đối với điều này, bạn có thể sử dụng Pax Exam, có một chút khó khăn để có được hang của, nhưng hoạt động thực sự tốt (đặc biệt là nếu bạn đang sử dụng maven và/hoặc các tính năng karaf). Ngoài ra, bạn có thể sử dụng TinyBundles để tự động tạo các gói/đoạn có thể triển khai từ bên trong thử nghiệm của bạn (rất thú vị) để loại bỏ các gói/đoạn khác để đảm bảo tích hợp liên gói mà không mang đến môi trường đầy đủ.

Đối với thử nghiệm tích hợp đơn vị hoặc quy mô nhỏ (nghĩa là không có vùng chứa) thì bạn chỉ có thể giả lập BundleContext (hoặc nếu sử dụng DS ComponentContext) nếu bạn cần.

Tôi có một chút không rõ ràng về câu hỏi của bạn trong các dấu đầu dòng. Nếu có một POJO bên trong thì bạn có trách nhiệm ràng buộc các phụ thuộc thông qua các setters, nếu không nếu nó tiếp xúc với bản ghi dịch vụ OSGi thì các phụ thuộc được giải quyết bởi khung công tác (DS hoặc ServiceTracker). Ngoài ra, việc phân lớp một thứ gì đó để ghi đè lên phương thức của người sáng tạo có nghĩa là bạn không còn thử nghiệm lớp gốc nữa - đây là một mùi mã - hãy thử tái cấu trúc nó để chuyển mã người tạo thành một lớp riêng biệt (hàm tạo hoặc setter), sau đó mã trình tạo mới này (tạo socket) có thể được kiểm tra độc lập (không xem xét đến OSGi hoặc thậm chí lớp giao thức mà nó sẽ được sử dụng).

+1

Nếu tôi sử dụng POJO trong thành phần OSGi đang chạy trong vùng chứa OSGi, chính thành phần đó phải tạo một cá thể của POJO, ví dụ: trong mã constrcutor vì container không thể tiêm nó. Làm thế nào tôi nên đánh chặn quá trình này trong một bài kiểm tra đơn vị? Tất nhiên tôi có thể tạo ra một phương thức setter sẽ ghi đè lên POJO đã tạo trước đó trong thành phần nhưng điều này cũng có một số mùi mã. "Chúng tôi có thực sự kiểm tra mã của thành phần như nó sẽ chạy trong vùng chứa không?" Một số tác dụng phụ như gọi POJO trong mã hàm khởi tạo có thể xảy ra và phá vỡ các thử nghiệm của tôi. –

+0

Tôi nghĩ rằng tôi làm theo, bạn có một Pojo tạo pojos khác bên trong constructor của nó (hoặc là trường khởi tạo), ví dụ: một lớp giao thức tạo ổ cắm?Nếu trường hợp này xảy ra thì bạn cần tách riêng việc tạo Socket từ lớp Protocol của bạn - bằng cách chuyển qua như một constructor arg hoặc áp dụng với một setter (nhưng loại bỏ bất kỳ việc tạo ra các Socket từ bên trong lớp Protocol). Bằng cách này bạn vượt qua trong một Socket giả lập để kiểm tra đơn vị, trong khi cho bó của bạn tạo ra một SocketServiceFactory trở về thực Sockets (sản xuất) và cho các thử nghiệm container giả lập dịch vụ này để trả lại Sock mock – earcam

+0

Perfect. Sử dụng một ServiceFactory minh bạch là excatly những gì tôi đang tìm kiếm. Trước đây tôi nghĩ ServiceFactories và ComponentFactories giống nhau. ;) –