2011-12-23 19 views
12

Tôi đang viết một lớp sẽ kế thừa một giao diện. Mã máy khách sẽ được viết cho giao diện đó và lớp được viết để hỗ trợ nó. Ý tưởng là sau này tôi sẽ viết các lớp khác cho giao diện đó, và các đối tượng của hai lớp khác nhau nên hoàn toàn có thể hoán đổi cho nhau. Thay vì viết một lớp kiểm tra cho lớp đầu tiên đó, tôi muốn viết một lớp cho giao diện.PHPUnit - Viết một lớp thử nghiệm cho một giao diện và kiểm tra các đối tượng bằng cách sử dụng một nhà máy

Kế hoạch của tôi là viết một lớp thử nghiệm sẽ lấy đối tượng nhà máy cho hàm khởi tạo (tiêm phụ thuộc) và sử dụng nhà máy để tạo các phiên bản mới của lớp đang thử nghiệm. Bằng cách đó, nếu tôi muốn kiểm tra ClassA, tôi có thể chuyển một đối tượng ClassAFactory đến hàm tạo của lớp thử nghiệm, và nếu tôi muốn kiểm tra ClassB, tôi sẽ vượt qua một đối tượng ClassBFactory. Cả hai lớp được thiết kế để có thể hoán đổi cho nhau, và vì chỉ có các phương thức công cộng mới được thử nghiệm, điều này có vẻ lý tưởng.

Nhưng còn thử nghiệm hàm tạo thì sao? Tôi sẽ viết tốt hơn một lớp thử nghiệm trừu tượng và hàm ý các bài kiểm tra hàm dựng trong các lớp thừa hưởng lớp kiểm tra trừu tượng (các lớp khác nhau có thể được khởi tạo khác nhau)?

Nếu tôi đã sử dụng các ý tưởng đầu tiên, tôi đoán tôi sẽ có một lớp thử nghiệm cho mỗi lớp học đang được thử nghiệm, như:

class ClassATest extends [PHPUnit test case] 
{ 
    $myFactory = new ClassAFactory(); 
    $myTest = new ClassTest($myFactory); 

    $myTest->test1(); 
    $myTest->test2(); 
    //etc. 
} 

cách tốt nhất để đi về vấn đề này là gì? Tôi muốn có một bài kiểm tra chung, để khi tôi viết các lớp mới để thực hiện giao diện chung, tôi có thể chỉ cần đặt một đối tượng của các thử nghiệm giống như được sử dụng cho những người khác. Nhưng, khi thấy các lớp khác nhau sẽ có các nhà xây dựng khác nhau, có lẽ việc viết một lớp thử nghiệm trừu tượng và mở rộng nó cho mỗi đối tượng mới sẽ tốt hơn? Bạn nghĩ sao?

Trả lời

6

Tôi nghĩ bạn cần cân nhắc lại kế hoạch của mình. Bạn không thể kiểm tra một giao diện và có một lý do chính đáng tại sao - các giao diện chỉ xác định API và không phải chức năng, kiểm tra chức năng kiểm tra. Hãy để tôi cung cấp cho bạn một ví dụ có thể hữu ích. Giả sử bạn có giao diện "nhắn tin". Vì vậy, bạn triển khai một EmailMessager và SMSMessager. Bây giờ bạn cần phải kiểm tra riêng biệt như với các EmailMessager bạn cần phải chắc chắn rằng nó đang làm công cụ của nó, có thể xác nhận người nhận (một địa chỉ email) và có thể ủy nhiệm việc gửi đến một lớp email vv Rõ ràng là một tin nhắn SMS sẽ khác nhau.

+1

Trong ví dụ cụ thể này, các lớp sẽ đại diện cho người nhận cho một danh sách gửi thư. Mặc dù họ sẽ có những cách khác nhau để thực hiện công việc của họ, họ sẽ lấy cùng một dữ liệu từ một khách hàng, và trả về cùng một kết quả - hoàn toàn có thể hoán đổi cho nhau. Dường như với tôi rằng nếu các đối tượng từ các lớp khác nhau sử dụng giao diện đó có thể hoán đổi cho nhau trong mã máy khách, chúng cũng có thể hoán đổi cho nhau trong mã thử nghiệm. Vì vậy, khi tôi nói rằng tôi muốn kiểm tra giao diện, ý tôi là, tôi muốn viết một bài kiểm tra cho giao diện đó, để kiểm tra một lớp có sử dụng giao diện đó. Điều đó có ý nghĩa đối với bạn? –

+1

Không, nó vẫn không có ý nghĩa. Đó không phải là cách tôi hiểu một giao diện để làm việc. Bạn có thể muốn một lớp cơ sở trừu tượng hơn là một giao diện để triển khai mã chung. Tôi không chắc những gì khác biệt về các lớp học của bạn ngoài dữ liệu. – liquorvicar

+0

Giả sử trên lớp, MailChimpRecipient sử dụng giao diện MailingListRecipient: máy khách đã mã hóa thêm ai đó vào danh sách bằng cách đặt địa chỉ email và thuộc tính tên của đối tượng người nhận, sau đó gọi phương thức để thêm chúng. Bây giờ, phương thức đó cho lớp MailChimp sẽ sử dụng API MailChimp để thêm chúng. Nói trong tương lai, tôi muốn lưu trữ danh sách gửi thư của riêng mình hoặc sử dụng một nhà cung cấp khác, tôi có thể chuyển đổi lớp đó với một lớp khác sử dụng giao diện MailingListRecipient. Lớp đó có thể làm điều gì đó hoàn toàn khác để thêm người nhận, nhưng nó vẫn có cùng dữ liệu. –

6

Bạn có thể tạo một trường hợp thử nghiệm trừu tượng với tất cả các phương pháp thử bằng cách sử dụng thuộc tính mà mỗi phân lớp sẽ đặt mà không yêu cầu nhà máy. Nó có thể kiểm tra những phẩm chất cố định mà tất cả các triển khai phải có.

abstract class IAdderTestCase extends PFTC 
{ 
    function testAdd() { 
     self::assertEquals(5, $this->fixture->add(2, 3)); 
    } 
    ... 
} 

class BasicAdderTest extends IAdderTestCase 
{ 
    function setUp() { 
     $this->fixture = new BasicAdder(); 
    } 
} 

PHPUnit sẽ gọi setUp() trước mỗi phương pháp thử nghiệm. Nó nên gọi tất cả các phương pháp thử nghiệm được kế thừa cho mỗi lớp con cụ thể cộng với bất kỳ lớp con bổ sung nào, ví dụ: để kiểm tra các nhà thầu.

+0

Cảm ơn vì điều đó! Điều đó có vẻ là cách tốt nhất để đi, khi tôi có thể thay đổi phương thức setUp cho mỗi subsclass khác nhau. –

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