Một cuộc thảo luận ngắn gọn về việc triển khai thử nghiệm đơn vị back-end .Net Core
In lạiTác giả: qq735679552Thời gian cập nhật: 27-09-2022 22:32:09294
CFSDN nhấn mạnh vào giá trị tạo ra nguồn mở và chúng tôi cam kết xây dựng nền tảng chia sẻ tài nguyên để mọi nhân viên CNTT có thể tìm thấy thế giới tuyệt vời của bạn tại đây.
Bài viết trên blog CFSDN này nói sơ qua về việc triển khai thử nghiệm đơn vị back-end .Net Core, được tác giả sưu tầm và biên soạn. Nếu bạn quan tâm đến bài viết này thì nhớ like nhé.
1. Lời nói đầu
Kiểm thử đơn vị luôn là một vấn đề tồn tại từ lâu mà “ai cũng biết nhiều về lợi ích nhưng chưa thực hiện vì nhiều lý do”. Cụ thể, có nên thực hiện thử nghiệm đơn vị hay không và mức độ thực hiện, mỗi dự án đều có tình huống riêng.
Bài viết này là quan điểm cá nhân của tôi về việc “làm thế nào để viết unit test tốt hơn”, tức là nó mang tính thực tế hơn và xen lẫn một số chia sẻ về mặt lý thuyết.
Khung kiểm thử đơn vị cho các ví dụ sau là xUnit và thư viện mô phỏng là Moq.
2. Tại sao cần kiểm thử đơn vị
Có rất nhiều ưu điểm, đây là hai ưu điểm mà cá nhân tôi cho là hiển nhiên.
2.1 Ngăn ngừa hồi quy
Thông thường khi phát triển các chức năng/mô-đun mới hoặc tái cấu trúc, việc kiểm tra sẽ được thực hiện để kiểm tra hồi quy các chức năng hiện có ban đầu nhằm xác minh xem các chức năng đã triển khai trước đó có còn chạy như mong đợi hay không.
Bằng cách sử dụng thử nghiệm đơn vị, bạn có thể chạy lại toàn bộ bộ thử nghiệm sau mỗi bản dựng hoặc thậm chí sau khi thay đổi một dòng mã, do đó giảm thiểu các lỗi hồi quy.
2.2 Giảm ghép mã
Viết bài kiểm tra đơn vị có thể trở nên khó khăn khi mã được liên kết chặt chẽ hoặc khi một phương thức quá dài. Khi kiểm thử đơn vị không được thực hiện, việc ghép mã có thể không rõ ràng. Việc viết các bài kiểm tra mã sẽ tách mã một cách tự nhiên, cải thiện chất lượng mã và khả năng bảo trì một cách ngụy trang.
3. Những nguyên tắc, chuẩn mực cơ bản
3.1 Nguyên tắc 3A
3A là "sắp xếp, hành động, khẳng định", thể hiện ba giai đoạn của phương pháp thử nghiệm đơn vị đủ tiêu chuẩn.
chuẩn bị trước
Cuộc gọi thực tế đến phương pháp thử nghiệm
Khẳng định về giá trị trả về
Phương pháp kiểm thử đơn vị Khả năng đọc là một trong những khía cạnh quan trọng nhất khi viết bài kiểm thử. Việc tách biệt các hoạt động này trong quá trình kiểm tra sẽ làm nổi bật rõ ràng các yếu tố phụ thuộc mà mã gọi yêu cầu, cách gọi và nội dung mà mã đang cố gắng khẳng định.
Vì vậy, khi viết bài kiểm tra đơn vị, vui lòng sử dụng nhận xét để đánh dấu từng giai đoạn của 3A, như trong ví dụ sau.
[Sự thật] public async Task VisitDataCompressExport_ShouldReturnEmptyResult_WhenFileTokenDoesNotExist(){ // sắp xếp var mockFiletokenStore = new Mock(); mockFiletokenStore .Setup(it => it.Get(It.IsAny())) .Returns(string.Empty); var controller = new StatController( mockFiletokenStore.Object, null); // act var actual = await controller.VisitDataCompressExport("faketoken"); // assert Assert.IsType(actual);}
3.2 Cố gắng tránh thử nghiệm trực tiếp các phương pháp riêng tư
Mặc dù các phương thức riêng tư có thể được kiểm tra trực tiếp thông qua sự phản ánh, nhưng trong hầu hết các trường hợp, không cần phải kiểm tra trực tiếp các phương thức riêng tư mà phải xác minh các phương thức riêng tư bằng cách thử nghiệm các phương thức công khai.
Hãy nghĩ theo cách này: các phương thức riêng tư không bao giờ tồn tại một cách biệt lập. Điều đáng quan tâm hơn là kết quả cuối cùng của việc gọi phương thức công khai của phương thức riêng tư.
3.3 Nguyên tắc tái thiết
Nếu một lớp/phương thức có nhiều phụ thuộc bên ngoài thì sẽ khó viết bài kiểm tra đơn vị. Sau đó, bạn nên xem xét liệu thiết kế hiện tại và các phần phụ thuộc có hợp lý hay không. Có một số khả năng tách rời? Chọn lọc lại phương pháp ban đầu thay vì chỉ viết nó ra...
3.4 Tránh khẳng định nhiều lần.
Nếu một phương pháp thử nghiệm có nhiều xác nhận, một hoặc một số xác nhận có thể không thành công, khiến toàn bộ phương pháp không thành công. Bằng cách này, về cơ bản chúng ta không thể biết tại sao thử nghiệm thất bại.
Vì vậy, nhìn chung có hai giải pháp.
Chia thành nhiều phương pháp thử nghiệm
Sử dụng thử nghiệm tham số hóa, như trong ví dụ sau
[Lý thuyết][InlineData(null)][InlineData("a")]public void Add_InputNullOrAlphabetic_ThrowsArgumentException(string input){ // sắp xếp var stringCalculator = new StringCalculator(); // act Hành động thực tế = () => stringCalculator.Add(input); // assert Assert.Throws(actual);}
Tất nhiên, nếu bạn đang xác nhận một đối tượng, bạn có thể xác nhận nhiều thuộc tính của đối tượng đó. Đây là một ngoại lệ.
3.5 Quy ước đặt tên tệp và phương thức Quy ước đặt tên tệp
Nói chung có hai loại. Ví dụ: các bài kiểm tra đơn vị cho các phương thức trong UserController phải được đặt trong UserControllerTest hoặc UserController_Test.
Tên phương pháp kiểm thử đơn vị
Tên phương thức của các bài kiểm tra đơn vị phải dễ đọc để có thể hiểu được toàn bộ phương pháp kiểm tra mà không cần bình luận. Định dạng phải tương tự như sau.
Khi viết bài kiểm thử đơn vị cho .Net Core, bạn phải chọn khung kiểm thử đơn vị, trong số ba khung kiểm thử đơn vị chính.
MsTest là framework thử nghiệm chính thức được sản xuất bởi Microsoft
Chưa bao giờ sử dụng NUnit
xUnit là một dự án nguồn mở thuộc .Net Foundation và là khung thử nghiệm đơn vị được sử dụng bởi nhiều kho lưu trữ (bao gồm cả thời gian chạy) trên dotnet github
Cho đến nay, sự phát triển của ba khung thử nghiệm chính rất khác nhau. Trong nhiều trường hợp, sự lựa chọn chỉ phụ thuộc vào sở thích cá nhân.
Moq là một thư viện mô phỏng rất phổ biến, miễn là có giao diện, nó có thể tự động tạo ra một đối tượng. Lớp dưới cùng sử dụng chức năng proxy động của Castle.
Cách sử dụng cơ bản.
Trong thực tế sử dụng, các tình huống sau có thể xảy ra.
lớp công khai UserController{ riêng tư chỉ đọc IUserService _userService; công khai UserController(IUserService userService) { _userService = userService; } [HttpGet("{id}")] công khai IActionResult GetUser(int id) { var user = _userService.GetUser(id); nếu (người dùng == null) { trả về NotFound(); } khác { ... } }}
Khi thực hiện kiểm thử đơn vị, bạn có thể sử dụng Moq để mô phỏng giá trị trả về của _userService.GetUser.
[Fact]public void GetUser_ShouldReturnNotFound_WhenCannotFoundUser(){ // sắp xếp // Tạo một đối tượng giả mới của IUserService var mockUserService = new Mock(); // Sử dụng moq để mô phỏng phương thức GetUs của IUserService: Trả về khi tham số đầu vào là 233 null mockUserService .Setup(it => it.GetUser(233)) .Return((User)null); var control = new UserController(mockUserService.Object); // act var real = control.GetUser(233) as NotFoundResult // xác nhận // Xác minh rằng phương thức GetUser của userService đã được gọi một lần và Tham số đầu vào là 233 mockUserService.Verify(it => it.GetUser(233), Times.AtmostOnce());}
4.3 Tự động cố định
Kho lưu trữ chính thức.
https://github.com/AutoFixture/AutoFixture 。
AutoFixture là thư viện điền dữ liệu giả được thiết kế để giảm thiểu giai đoạn sắp xếp trong 3A, giúp nhà phát triển dễ dàng tạo các đối tượng chứa dữ liệu thử nghiệm hơn, để họ có thể tập trung hơn vào việc thiết kế trường hợp thử nghiệm.
Cách sử dụng cơ bản.
Trực tiếp sử dụng phương pháp sau để tạo dữ liệu giả được gõ mạnh.
[Sự thật]public void IntroductoryTest(){ // sắp xếp Fixture fixture = new Fixture(); int expectedNumber = fixture.Create(); MyClass sut = fixture.Create(); // act int result = sut.Echo(expectedNumber); // assert Assert.Equal(expectedNumber, result);}
Các ví dụ trên cũng có thể được kết hợp với chính khung thử nghiệm, chẳng hạn như xUnit.
[Lý thuyết, Dữ liệu tự động]public void IntroductoryTest( int expectedNumber, MyClass sut){ // act int result = sut.Echo(expectedNumber); // assert Assert.Equal(expectedNumber, result);}
5. Kết hợp với việc sử dụng Visual Studio trong thực tế
Visual Studio cung cấp hỗ trợ kiểm tra đơn vị hoàn chỉnh, bao gồm chạy, viết và gỡ lỗi các bài kiểm tra đơn vị. Và xem phạm vi kiểm tra đơn vị, v.v.
5.1 Cách chạy thử nghiệm đơn vị trong Visual Studio
5.2 Cách xem phạm vi kiểm thử đơn vị trong Visual Studio
Các chức năng sau yêu cầu phiên bản Visual Studio 2019 Enterprise và phiên bản cộng đồng không có chức năng này.
Cách kiểm tra vùng phủ sóng.
Trong cửa sổ kiểm tra, nhấp chuột phải vào điểm nhóm kiểm tra tương ứng
Nhấp vào "Phân tích phạm vi mã" bên dưới
6. Mô phỏng các kịch bản thường gặp trong thực tế
chủ yếu.
6.1 Bộ dữ liệu
Trong quá trình sử dụng EF Core, việc mock DbSet là một trở ngại không thể tránh khỏi.
Phương pháp một.
Hãy tham khảo đáp án ở link dưới đây để tự mình gói gọn lại nhé.
Sử dụng các thư viện làm sẵn (cũng được đóng gói dựa trên phương pháp trên).
Địa chỉ kho:
https://github.com/romantitov/MockQueryable 。
Ví dụ sử dụng.
// 1. Tạo một Danh sách mô phỏngvar user = new List(){ new UserEntity{LastName = "ExistLastName", DateOfBirth = DateTime.Parse("20/01/2012")} khi kiểm tra . ..}; // 2. Chuyển đổi sang DbSetvar mockUsers = thông qua phương thức mở rộng user.AsQueryable().BuildMock();// 3. Gán giá trị cho thuộc tính Users var trong DbContext của mockDbContext = new Mock();mockDbContext .Setup(it => it.Users) . Trả về(mockUsers );
6.2 Máy khách Http
Các kịch bản sử dụng RestEase/Refit.
Nếu bạn đang sử dụng thư viện của bên thứ ba như RestEase hoặc Refit, thì định nghĩa của một giao diện cụ thể về cơ bản là một giao diện, vì vậy bạn có thể trực tiếp sử dụng moq để mô phỏng phương thức.
Và nên sử dụng phương pháp này.
Nhà máy IHttpClient.
Nếu bạn đang sử dụng phương thức IHttpClientFactory đi kèm với .Net Core để yêu cầu giao diện bên ngoài, bạn có thể tham khảo phương pháp sau để mô phỏng IHttpClientFactory.
Vì LogError của ILogger và các phương thức khác là các phương thức mở rộng nên không cần thực hiện mô phỏng cấp phương thức đặc biệt.
Lớp trợ giúp được gói gọn cho một số tình huống sử dụng hàng ngày. Bạn có thể sử dụng lớp trợ giúp sau cho Mô phỏng và Xác minh.
lớp tĩnh công khai LoggerHelper{ công khai tĩnh Mock<>> LoggerMock() trong đó T : lớp { trả về Mock<>> mới(); } công khai tĩnh void VerifyLog(mock<>> này loggerMock, LogLevel level, string containsMessage, Times times) { loggerMock.Verify( x => x.Log( level, It.IsAny(), It.Is((o, t) => o.ToString().Contains(containMessage)), It.IsAny(), (Func)It.IsAny
Cách sử dụng.
[Sự thật]public void Echo_ShouldLogInformation(){ // sắp xếp var mockLogger = LoggerHelpe.LoggerMock(); var controller = new UserController(mockLogger.Object); // hành động controller.Echo(); // khẳng định mockLogger.VerifyLog(LogLevel.Information, "hello", Times.Once());}
7. Mở rộng
7.1 Giới thiệu về TDD
TDD là tên viết tắt tiếng Anh của Phát triển dựa trên thử nghiệm. Nói chung, các kịch bản khác nhau để thử nghiệm đơn vị được thiết kế trước khi viết mã kinh doanh thực sự và tạo ra một mạng lưới an toàn để loại bỏ các lỗi trong nôi.
Mô hình phát triển này đặt thử nghiệm lên hàng đầu và có yêu cầu cao hơn đối với nhóm phát triển, đồng thời có thể gặp nhiều khó khăn thực tế trong quá trình triển khai. Hướng dẫn chi tiết có thể được tìm thấy dưới đây.
Đến đây là kết thúc bài viết về việc triển khai thử nghiệm đơn vị back-end .Net Core. Để biết thêm thông tin về thử nghiệm đơn vị .Net Core, vui lòng tìm kiếm các bài viết trước của tôi hoặc tiếp tục duyệt qua các bài viết liên quan sau. Hãy ủng hộ tôi! .
Liên kết gốc: https://www.cnblogs.com/baoshu/p/14500273.html.
Cuối cùng, bài viết này về việc triển khai thử nghiệm đơn vị back-end .Net Core kết thúc tại đây. Nếu bạn muốn biết thêm về việc triển khai thử nghiệm đơn vị back-end .Net Core, vui lòng tìm kiếm bài viết CFSDN hoặc tiếp tục Duyệt qua liên quan. bài viết, hy vọng bạn sẽ ủng hộ blog của tôi trong tương lai! .
Khi tạo trang asp.net sử dụng .NET framework, máy khách truy cập trang đó có cần cài đặt .NET framework trên máy tính của họ không? tức là. Người dùng truy cập www.fakesite.com/default.aspx và nếu họ chưa cài đặt framework, anh ta
Tôi đã đọc rất nhiều blog khác nhau và các câu hỏi về StackOverflow để cố gắng tìm câu trả lời cho câu hỏi của mình, nhưng cuối cùng tôi không tìm thấy gì, vì vậy tôi nghĩ tôi sẽ tự mình đặt câu hỏi. Tôi đang xây dựng một ứng dụng có một chuỗi công việc dài hạn thực hiện một số
Đã khóa. Câu hỏi này và câu trả lời của nó bị khóa vì câu hỏi này lạc đề nhưng có ý nghĩa lịch sử. Không chấp nhận câu trả lời hoặc tương tác mới vào thời điểm này. Tôi luôn tự hỏi tại sao Microsoft lại chọn một cái tên kỳ lạ, không thân thiện với công cụ tìm kiếm cho một nền tảng tuyệt vời như vậy. Họ chỉ
Sự khác biệt giữa .Net Framework .Net .NET Standard 1. .NET Framework Trong tương lai, .NET Framework có thể trở thành dĩ vãng nhưng nó vẫn được sử dụng ở nhiều nơi. Bộ này
Tôi có một dịch vụ web sử dụng dịch vụ web của bên thứ ba qua https qua kết nối riêng tư và tôi đã áp dụng ServicePointManager.ServerCertificateValidationCallbac
Tôi không tìm thấy bất kỳ quy ước đặt tên nào được chấp nhận trên web cho các giải pháp .NET bao gồm các dự án .NET Standard, .NET Core và .NET Framework. Trong trường hợp của tôi, chúng tôi có những điều sau đây trong dự án .NET Framework
.NET Compact có phải là tập hợp con hoàn hảo của .NET không? Giả sử tôi tính đến kích thước màn hình và các hạn chế khác, đồng thời tránh các lớp và phương thức mà .NET Compact không hỗ trợ hoặc .NET Compact là một GUI khác và không tương thích
Tôi hiện đang sử dụng asp.net mvc và tự hỏi liệu sử dụng Json hoặc Json.Net tích hợp có phải là lựa chọn tốt hơn hay không, nhưng tôi không chắc liệu cái này có lợi thế hơn cái kia hay không. Ngoài ra, nếu tôi đã chọn đi theo tuyến đường Json.Net, tôi nên chọn
Trong Visual Studio, bạn có thể tạo ít nhất ba loại thư viện lớp khác nhau: Thư viện lớp (.NET Framework) Thư viện lớp (.NET Standard) Thư viện lớp (.NET Core) Trong khi loại đầu tiên là thứ chúng tôi đã sử dụng trong nhiều năm , nhưng tôi
Sự khác biệt giữa .NET và ASP.NET là gì? Chúng có liên quan như thế nào? Câu trả lời hay nhất ASP.Net được xây dựng trên khung .Net và cung cấp các tính năng bổ sung để phát triển web. Bạn có thể xem bài viết trên wikipedia
Tôi có cần cài đặt .net framework 1.1 và 2.0 trước khi cài đặt phiên bản cao hơn (3.0) không? Hay chỉ cần cài đặt khung 3.0 và cung cấp hỗ trợ cho phần mềm được viết trên các phiên bản khung trước đó là đủ? Cảm ơn, Liran Câu trả lời hay nhất Không, bạn không cần phải cài đặt khung trước đó. TÔI
Tôi đang làm việc trên một dự án nơi mọi người có thể "cập nhật" các danh mục, ví dụ: thay đổi tên của danh mục. Tôi nhận được thông báo sau. Cái này được gọi sau khi nhấp vào nút cập nhật bằng câu lệnh SQL
Lớp .NET System.Net.CookieContainer có an toàn không? --CẬP NHẬT: Trả lời chính---Có cách nào để đảm bảo rằng các biến được sửa đổi trong yêu cầu không đồng bộ (tức là HttpWebRequest.Coo
Tôi đang sử dụng JScript.NET để viết tập lệnh trong ứng dụng C# WinForms mà tôi đang viết. Nó hoạt động tốt, nhưng tôi vừa thử đưa một số xử lý ngoại lệ vào tập lệnh và tôi không thể tìm ra cách để biết loại ngoại lệ mà mã C# của tôi đã ném ra
Tôi đã sử dụng mã như thế này: http://msdn.microsoft.com/en-us/library/dw70f090.aspx để truy cập cơ sở dữ liệu trước khi làm việc trong ASP.NET (2-3 năm trước). Tôi đã không nhận ra mình đã
Vì Trình quản lý cấu hình không tồn tại trong .NET Standard, nên cách tốt nhất để truy xuất cài đặt ứng dụng cho tập hợp thực thi, web.config hoặc appSettings.{env
Tôi là một lập trình viên xuất sắc, rất giỏi!