Kiểm thử đơn vị phương thức nội bộ trong thư viện VS2017 .Net Standard


150

Tôi hiện đang chơi xung quanh với Ứng viên phát hành Visual Studio 2017 mới nhất bằng cách tạo thư viện .Net Standard 1.6. Tôi đang sử dụng xUnit để kiểm tra mã của tôi và tự hỏi liệu bạn có thể kiểm tra các phương thức nội bộ trong VS2017 không.

Tôi nhớ rằng bạn có thể tất cả một lớp hộiInInfo.cs trong VS2015 sẽ cho phép các dự án được chỉ định để xem các phương thức nội bộ

[assembly:InternalsVisibleTo("MyTests")]

Vì không có lớp AssociationInfo.cs trong các dự án VS2017 .Net Standard, tôi đã tự hỏi liệu bạn có thể kiểm tra các phương thức nội bộ không?


3
Bạn nên có thể đơn vị kiểm tra mã của bạn từ chức năng từ bên ngoài có thể nhìn thấy một mình. Rốt cuộc, nếu không có đường dẫn logic từ mã bên ngoài có thể tiếp cận các phương thức bên trong đó thì chúng sẽ làm gì ở đó ngay từ đầu?
David

3
@David Tôi có thể và đã làm điều này nhưng tôi đã đặt các bài kiểm tra đơn vị đơn giản xung quanh một số lớp bên trong trước đây. Chỉ cần rõ ràng hơn trong thử nghiệm.
Phil Murray

5
AFAIK, bạn có thể đặt thuộc tính này vào bất kỳ tệp nào khác, bên ngoài namespacekhối và nó sẽ biên dịch. Không nên có bất cứ điều gì kỳ diệu về AssemblyInfo.cs. Nó không hoạt động à? Tất nhiên, bạn cần thêm usingmệnh đề đúng hoặc sử dụng thuộc tính đủ điều kiện [assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Something")].
Groo

1
@David Nếu bạn đang tạo một thư viện với các lớp bên trong và bạn cần kiểm tra và mô phỏng các lớp này, InternalsVisibleTothì rất quan trọng - ví dụ ở đây - stackoverflow.com/a/17574183/43453
PandaWood

Câu trả lời:


210

Theo tài liệu .NET choInternalsVisibleToAttribute :

Thuộc tính được áp dụng ở cấp độ lắp ráp. Điều này có nghĩa là nó có thể được bao gồm ở phần đầu của tệp mã nguồn hoặc nó có thể được bao gồm trong tệp BangInfo trong một dự án Visual Studio.

Nói cách khác, bạn có thể chỉ cần đặt nó trong tệp .cs được đặt tên tùy ý của mình và nó sẽ hoạt động tốt:

// some .cs file included in your project
using System.Runtime.CompilerServices;
[assembly:InternalsVisibleTo("MyTests")]

1
@PhilM bồ: cũng có vẻ như có một cài đặt cho phép bạn tạo một AssemblyInfo.cstệp "cổ điển" như được giải thích ở đây . Mặt khác, tất cả các thuộc tính như "mô tả", "bản quyền" và các nội dung khác được lưu trữ bên trong tệp .csproj.
Groo

43

Như được mô tả ở đây:

https://blog.sanderaernouts.com/make-iternals-visible-with-new-csproj-format

Có thể thêm thuộc tính hiển thị nội bộ trong tệp dự án bằng cách thêm một Itemgroup khác:

<ItemGroup>
    <AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleTo">
        <_Parameter1>$(AssemblyName).Tests</_Parameter1>
    </AssemblyAttribute>
</ItemGroup>

hoặc thậm chí:

<ItemGroup>
    <AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleTo">
        <_Parameter1>$(MSBuildProjectName).Tests</_Parameter1>
    </AssemblyAttribute>
</ItemGroup>

Tôi thích giải pháp đó vì tệp dự án dường như là nơi thích hợp để xác định những mối quan tâm đó.


8

Trong khi câu trả lời đầu tiên là hoàn toàn tốt. Nếu bạn cảm thấy bạn vẫn muốn làm điều này trong bản gốc, AssemblyInfobạn luôn có thể chọn không tự động tạo tệp và thêm nó theo cách thủ công.

<PropertyGroup>
   <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
</PropertyGroup>

Để biết thêm thông tin: https://stackoverflow.com/a/47075759/869033


5

Thuộc tính "InternalsVisibleTo" là chìa khóa cho bất kỳ loại "hộp trắng" nào (thuật ngữ của thập kỷ, tôi đoán) thử nghiệm cho .Net. Nó có thể được đặt trong bất kỳ tệp c # nào có thuộc tính "lắp ráp" ở mặt trước. Lưu ý rằng MS DOCs nói rằng tên lắp ráp phải đủ điều kiện bằng mã thông báo khóa công khai, nếu nó được ký. Đôi khi điều đó không hoạt động và người ta phải sử dụng khóa công khai đầy đủ ở vị trí của nó. Truy cập vào nội bộ là chìa khóa để kiểm tra các hệ thống đồng thời và trong nhiều tình huống khác. Xem https://www.amazon.com/xUnit-Test-Potypes-Refactoring-Code/dp/0131495054 . Trong cuốn sách này, Meszaros mô tả một loạt các phong cách mã hóa về cơ bản tạo thành cách tiếp cận "Thiết kế để thử nghiệm" để phát triển chương trình. Ít nhất đó là cách tôi đã sử dụng nó trong nhiều năm qua.

THÊM: Xin lỗi, tôi đã không ở đây một thời gian. Một cách tiếp cận được gọi là phương pháp "phân lớp thử nghiệm" của Meszaros. Một lần nữa, người ta phải sử dụng "internalsvisableto" để truy cập vào các phần bên trong của lớp cơ sở. Đây là một giải pháp tuyệt vời, nhưng nó không hoạt động đối với các lớp kín. Khi tôi dạy "Thiết kế để kiểm tra", tôi đề nghị rằng đó là một trong những điều bắt buộc phải được "tiền chế" vào các lớp cơ sở để cung cấp khả năng kiểm tra. Nó phải trở thành gần như một điều văn hóa. Thiết kế một lớp cơ sở "cơ sở" không được tiết lộ. Gọi nó là UnsealsBaseClass hoặc một cái gì đó dễ nhận biết. Đây là lớp được phân lớp để kiểm tra. Nó cũng được phân lớp để xây dựng lớp niêm phong sản xuất, thường chỉ khác nhau trong các hàm tạo mà nó trưng ra. Tôi làm việc trong ngành công nghiệp hạt nhân và các yêu cầu thử nghiệm được thực hiện RẤT nghiêm túc. Vì vậy, tôi phải suy nghĩ về những điều này mọi lúc. Nhân tiện, việc để lại các móc kiểm tra trong mã sản xuất không được coi là một vấn đề trong lĩnh vực của chúng tôi, miễn là chúng là "nội bộ" trong triển khai .Net. Sự phân nhánh của KHÔNG kiểm tra một cái gì đó có thể khá sâu sắc.


1

Một cách khác là sử dụng lớp công khai 'bao bọc' TestMyFoo bên trong dự án đích có các phương thức và kế thừa công khai từ lớp bạn cần kiểm tra (ví dụ MyFoo). Các phương thức công khai này chỉ đơn giản gọi qua lớp cơ sở mà bạn muốn kiểm tra.

Nó không phải là "lý tưởng" khi bạn kết thúc việc thử nghiệm móc trong dự án mục tiêu của mình. Nhưng hãy xem xét những chiếc xe đáng tin cậy hiện đại xuất xưởng với các cổng chẩn đoán và tàu điện tử đáng tin cậy hiện đại có kết nối JTAG. Nhưng không ai đủ ngớ ngẩn để lái xe của họ bằng cổng chẩn đoán.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.