2010-10-27 28 views
11

xem xét:Làm thế nào để viết một bài kiểm tra đơn vị cho "T phải là một kiểu tham chiếu"?

class MyClass<T> where T : class 
{ 
} 

Trong trường hợp đó, mệnh đề where đang thực thi một đặc điểm kỹ thuật mà MyClass chỉ là một chung của một loại tài liệu tham khảo.

Lý tưởng nhất là tôi nên có một bài kiểm tra đơn vị kiểm tra đặc điểm kỹ thuật này. Tuy nhiên, thử nghiệm đơn vị này rõ ràng sẽ không hoạt động, nhưng nó giải thích những gì tôi đang cố gắng hoàn thành:

[Test] 
[DoesNotCompile()] 
public void T_must_be_a_reference_type() 
{ 
    var test = new MyClass<int>(); 
} 

Tôi có thể làm gì để kiểm tra thông số được thực hiện bằng cách không cho phép biên dịch mã?

EDIT:

Thông tin thêm: Ok, vậy lý luận của tôi để làm điều này (haha) là tôi đã làm theo một phương pháp TDD, trong đó bạn không thể viết bất kỳ mã trừ khi bạn có một kiểm tra đơn vị không thành công. Giả sử bạn có điều này:

class MyClass<T> { } 

Bạn có thể viết bài kiểm tra nào thất bại trừ khi T là lớp học? Một cái gì đó như default(T) == null?

Hơn nữa EDIT:

Vì vậy, sau một "nguyên nhân gốc rễ phân tích" về vấn đề này, vấn đề là tôi đã dựa vào default(T)null trong một người tiêu dùng của lớp này, một cách tiềm ẩn. Tôi đã có thể tái cấu trúc mã người tiêu dùng đó thành một lớp khác, và chỉ định một hạn chế kiểu chung ở đó (giới hạn nó thành class), điều đó có hiệu quả làm cho mã đó không biên dịch nếu ai đó xóa bỏ giới hạn trên lớp mà tôi đang nói ở trên.

+3

Tại sao bạn không kiểm tra đơn vị rằng lớp được đặt tên là 'MyClass'? – SLaks

+0

@SLaks: kỹ thuật var test = new MyClass (); sẽ kiểm tra điều đó, phải không? –

+0

Tôi nghĩ @SLaks đã sử dụng mỉa mai để chứng minh rằng bạn không cần phải kiểm tra trình biên dịch ... đó là công việc của Microsoft. – TheCloudlessSky

Trả lời

25

Tại sao bạn cần thử nghiệm đơn vị cho điều này? Bạn có viết thử nghiệm đơn vị cho một phương thức như

public void Foo(string x) 

để kiểm tra xem nó chỉ có thể lấy chuỗi chứ không phải số nguyên không? Nếu không, bạn thấy điều gì là khác biệt?

CHỈNH SỬA: Chỉ để hơi kém hay thay đổi: trong trường hợp này, thông số được xác thực bằng tuyên bố . Kiểm tra thường phải kiểm tra hành vi . Đó là một trong những điều tôi thích về Code Contracts: Tôi không cảm thấy cần phải kiểm tra các hợp đồng trừ khi họ thể hiện một cái gì đó phức tạp - trong trường hợp đó là sự phức tạp mà tôi muốn thử nghiệm, chứ không phải là "các hợp đồng được thực thi" .

EDIT: Để đáp ứng cho câu hỏi chỉnh sửa:

kiểm tra gì bạn có thể viết rằng sẽ thất bại trừ khi T là một lớp học?

Bạn thể ghi cái gì đó như:

Type definition = typeof(MyClass<>); 
Assert.Throws<ArgumentException>(() => definition.MakeGenericType(typeof(int))); 

Tuy nhiên, điều đó dường như được đi ngược lại mục đích thực sự của thử nghiệm ...

+0

Vâng, tôi đang cố gắng để làm cho bài kiểm tra đơn vị của tôi bao gồm tất cả các thông số kỹ thuật cho các đơn vị được kiểm tra. –

+0

@Jon Funny, chúng tôi đã nghĩ chính xác cùng một ví dụ –

+2

@Scott Whitlock - Nhưng đơn giản là việc biên dịch mã ** là ** thử nghiệm của bạn. –

9

Bạn không nên kiểm tra xem trình biên dịch có hoạt động hay không. Nếu bạn chỉ định mã này, điều này là đủ. Từ góc độ mã, điều này gần giống như sau:

[Test] 
public void Test_whether_add_works() 
{ 
    int i = 1 + 2; 

    Assert.AreEqual(3, i); 
} 
+4

'[Test] public void Running1984() {Assert.AreEqual (5, 2 + 2); } ' –

+0

Hihi, Radiohead. –

2

Bạn có viết một bài kiểm tra đơn vị chính xác không? Dường như bạn sẽ thử trình biên dịch C# nhưng không phải mã của bạn.

3

Đây là một câu hỏi lớn! Vì vậy, nhiều đồng ý với cách tiếp cận thử nghiệm hướng của bạn. Những gì bạn đang đấu tranh với thực sự là cuộc đụng độ của hai mô hình. Mô hình cũ mà các chương trình phải được chứng minh chính xác bằng cách sử dụng toán học mà không cần chạy chúng (một di sản của tổ tiên nghề nghiệp của chúng ta trong toán học) và mô hình mới mà chương trình phải được chứng minh chính xác bằng cách thực hiện với các trường hợp sử dụng ví dụ. Vì vậy, những gì bạn sắp thử là áp dụng thực hành của mô hình mới trên một tạo tác của mô hình cũ, mà tất nhiên sẽ không thực sự làm việc ...

Thông tin thêm về sự phân đôi các loại và kiểm tra, xem bài viết tuyệt vời này của Chris Smith, http://web.archive.org/web/20080822101209/http://www.pphsg.org/cdsmith/types.html

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