2010-05-14 34 views
16

Khi tôi kiểm tra việc thực thi phương thức tạo chuỗi con, kiểm tra JUnit kết thúc trước chuỗi con và giết nó.JUnit chấm dứt chủ đề con

Làm cách nào để buộc JUnit phải đợi chuỗi con hoàn thành quá trình thực thi?

Cảm ơn

Trả lời

7

Sau khi đọc câu hỏi và một số nhận xét, có vẻ như những gì bạn cần là một kỹ thuật để kiểm tra đơn vị hoạt động không đồng bộ. doSomething() trả về ngay lập tức, nhưng bạn muốn mã kiểm tra chờ kết thúc, và sau đó thực hiện một số xác nhận hợp lệ.

Vấn đề là kiểm tra không nhận thức được các chủ đề được sinh ra bởi cuộc gọi, vì vậy rõ ràng nó không có phương tiện chờ đợi cho họ. Người ta có thể nghĩ ra nhiều cách phức tạp (và có thể thiếu sót) để giải quyết vấn đề này, nhưng theo tôi thì có một vấn đề thiết kế ở đây. Một bài kiểm tra đơn vị nên mô phỏng một khách hàng của một số API, và nó không nên giả định bất cứ điều gì về việc thực hiện; Nó chỉ nên kiểm tra chức năng, như được phản ánh bởi API và tài liệu của nó. Vì vậy, tôi sẽ tránh cố gắng để phát hiện và theo dõi các chủ đề được tạo ra bởi các cuộc gọi asynch. Thay vào đó, tôi sẽ cải thiện API của lớp được kiểm tra, nếu cần. Lớp mà cuộc gọi asynch thuộc về nên cung cấp một số cơ chế để phát hiện chấm dứt. Tôi có thể nghĩ đến 3 cách khác nhau, nhưng có lẽ hơn:

1) Cho phép đăng ký người nghe đó được thông báo khi hoạt động được hoàn thành

2) Cung cấp một phiên bản đồng bộ của phẫu thuật. Việc triển khai có thể gọi phiên bản asynch và sau đó chặn cho đến khi hoàn thành. Nếu lớp không được để lộ một phương thức như vậy, khả năng hiển thị của nó có thể được giảm xuống thành gói được bảo vệ, để kiểm tra có thể truy cập nó.

3) Sử dụng mẫu chờ thông báo, trên một số đối tượng hiển thị.

Nếu lớp học không cung cấp cơ chế như vậy, thì nó không thực sự có thể kiểm chứng được, và tệ hơn, nó có lẽ không thể tái sử dụng được.

2

Hãy thử sử dụng thread.join() trên chuỗi đã tạo. Điều này sẽ chờ đợi cho rằng thread để chết.

Chỉnh sửa: để tránh điều này, hãy thử Thread.getThreadGroup().setDaemon(true); trong thử nghiệm hoặc có thể trong phương thức setUp(). Tôi đã không thử nghiệm này mặc dù.

Nhóm chủ đề daemon sẽ tự động bị hủy khi chủ đề cuối cùng bị dừng hoặc nhóm chủ đề cuối cùng bị hủy.

Tôi tự hỏi nếu JUnit đang gọi số System.exit() hoặc một cái gì đó ngay khi thử nghiệm kết thúc, tuy nhiên.

+0

Thực ra tôi sẽ tránh giải pháp này, thay vào đó, tôi đang tìm cách tốt hơn để chạy loại thử nghiệm này và buộc chủ đề chính phải đợi đến cuối con của nó. – Mark

+0

@Marco: bạn có thể vui lòng xây dựng không? có gì sai với giải pháp của Chris? –

+0

Tôi đang thử nghiệm một phương thức doSomething() khởi tạo nội bộ một số luồng cập nhật một số bảng db. Những gì tôi muốn làm là chạy phương thức này bên trong bài kiểm tra JUnit của tôi và sau đó kiểm tra xem tất cả các chỉnh sửa trên cơ sở dữ liệu đã được lưu thành công chưa. Điều quan trọng đối với phương thức doSomething() là không tham gia các luồng khi chúng được tạo ra, và vì vậy tôi không thể áp dụng giải pháp join(). – Mark

0

Có lẽ nhóm chủ đề của bạn với một ExecutorService, sau đó sử dụng shutdownawaitTermination phương pháp?

Điều kiện là sử dụng Runnable hoặc Future, không phải Chủ đề.

+1

JUnit không đợi cho ExecutorService kết thúc. – koppor

1

Kỹ thuật cơ bản mà @Eyal được nêu là những gì ConcurrentUnit được thiết kế cho.Việc sử dụng chung là:

  1. đẻ trứng một số đề
  2. Có thread chờ đợi chính hoặc ngủ
  3. Thực hiện khẳng định từ bên trong đề người lao động (trong đó qua ConcurrentUnit, được báo cáo lại cho các chủ đề chính)
  4. Tiếp tục chuỗi chính từ một trong các chuỗi công nhân khi tất cả các xác nhận hoàn thành

Xem trang ConcurrentUnit để biết thêm thông tin.

0
 while (s.isRunning()) { 
      try { 
       Thread.sleep(SLEEP_TIME); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
     } 

Bạn có thể thử chặn chuỗi JUnit và yêu cầu hoàn thành chuỗi. Thread.sleep() là cần thiết để chủ đề của bạn không hog CPU. Trong ví dụ này s sẽ là chủ đề của bạn, bạn sẽ cần phải có một phương thức isRunning() để bạn có thể kiểm tra xem chuỗi đó vẫn chạy mỗi SLEEP_TIME mili giây. Tôi biết đây không phải là giải pháp lớn nhất nhưng nếu bạn chỉ có 2 chủ đề và bạn không muốn JUnit giết chết thread của bạn hoạt động này. Vòng lặp while với nguyên nhân chuỗi JUnit này vẫn còn sống và chờ cho luồng khác của bạn kết thúc.

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