Là tĩnh phổ biến trên toàn thế giới, Evil Evil để thử nghiệm đơn vị và nếu vậy tại sao Resharper đề xuất nó? [đóng cửa]


85

Tôi đã thấy rằng chỉ có 3 cách để phụ thuộc kiểm tra đơn vị (mock / stub) là tĩnh trong C # .NET:

Cho rằng hai trong số này không miễn phí và một bản chưa đạt được bản phát hành 1.0, việc nhạo báng các công cụ tĩnh không quá dễ dàng.

Điều đó có làm cho các phương thức tĩnh và "ác" như vậy (theo nghĩa thử nghiệm đơn vị) không? Và nếu vậy, tại sao resharper muốn tôi làm bất cứ điều gì có thể tĩnh, tĩnh? (Giả sử chia sẻ lại không phải là "xấu xa".)

Làm rõ: Tôi đang nói về kịch bản khi bạn muốn kiểm tra đơn vị một phương pháp và phương pháp mà các cuộc gọi một phương pháp tĩnh trong một khác nhau đơn vị / lớp. Theo hầu hết các định nghĩa về kiểm thử đơn vị, nếu bạn chỉ để phương thức được kiểm tra gọi phương thức tĩnh trong đơn vị / lớp khác thì bạn không kiểm thử đơn vị, bạn đang kiểm thử tích hợp . (Hữu ích, nhưng không phải là một bài kiểm tra đơn vị.)


3
TheLQ: Bạn có thể. Tôi tin rằng anh ta đang nói về việc không thể kiểm tra các phương thức tĩnh vì phần lớn thời gian nó chạm vào các biến tĩnh. Do đó thay đổi trạng thái sau và giữa thử nghiệm.

26
Cá nhân tôi nghĩ rằng bạn đang đưa định nghĩa về "đơn vị" quá xa. "Đơn vị" phải là "đơn vị nhỏ nhất có ý nghĩa để kiểm tra cách ly". Đó có thể là một phương pháp, nó có thể nhiều hơn thế. Nếu phương thức tĩnh không có trạng thái và được kiểm tra tốt thì việc gọi thử nghiệm đơn vị thứ hai là nó (IMO) không phải là vấn đề.
mlk

10
"Cá nhân tôi nghĩ rằng bạn đang đưa định nghĩa về" đơn vị "quá xa." Không, chỉ là anh ấy đang sử dụng tiêu chuẩn và bạn đang tạo nên định nghĩa của riêng bạn.

7
"tại sao resharper muốn tôi làm bất cứ điều gì có thể tĩnh, tĩnh?" Resharper không muốn bạn làm bất cứ điều gì. Nó chỉ đơn thuần là làm cho bạn biết rằng việc sửa đổi là có thể và có thể mong muốn từ một POV phân tích mã. Resharper không phải là sự thay thế cho phán đoán của riêng bạn!
Adam Naylor

4
@ axitzombie24. Các phương thức thông thường cũng có thể sửa đổi trạng thái tĩnh vì vậy chúng sẽ "xấu" như các phương thức tĩnh. Việc họ cũng có thể sửa đổi trạng thái với vòng đời ngắn hơn khiến họ càng nguy hiểm hơn. (Tôi không ủng hộ các phương thức tĩnh, nhưng quan điểm về sửa đổi trạng thái cũng là một đòn mạnh đối với các phương thức thông thường, thậm chí còn hơn thế)
mike30

Câu trả lời:


105

Nhìn vào các câu trả lời khác ở đây, tôi nghĩ rằng có thể có một số nhầm lẫn giữa các phương thức tĩnh giữ trạng thái tĩnh hoặc gây ra tác dụng phụ (nghe có vẻ như là một ý tưởng thực sự tồi tệ) và các phương thức tĩnh chỉ trả về một giá trị.

Các phương pháp tĩnh không có trạng thái và không gây ra tác dụng phụ nên có thể dễ dàng kiểm tra đơn vị. Trên thực tế, tôi coi các phương pháp đó là một dạng lập trình chức năng "người nghèo"; bạn trao cho phương thức một đối tượng hoặc giá trị và nó trả về một đối tượng hoặc giá trị. Chỉ có bấy nhiêu thôi. Tôi không thấy các phương pháp như vậy sẽ ảnh hưởng tiêu cực đến thử nghiệm đơn vị như thế nào.


44
Phương thức tĩnh là đơn vị có thể kiểm tra được, nhưng còn các phương thức gọi phương thức tĩnh thì sao? Nếu người gọi ở trong một lớp khác thì họ có một sự phụ thuộc cần được tách rời để làm một bài kiểm tra đơn vị.
Núi lửa

22
@Vaccano: Nhưng nếu bạn viết các phương thức tĩnh không giữ trạng thái và không có tác dụng phụ, thì chúng ít nhiều có chức năng tương đương với một sơ khai.
Robert Harvey

20
Những cái đơn giản có thể. Nhưng những cái phức tạp hơn có thể bắt đầu đưa ra các ngoại lệ và có kết quả đầu ra không được mong đợi (và nên được bắt gặp trong thử nghiệm đơn vị cho phương thức tĩnh, không phải trong thử nghiệm đơn vị cho người gọi phương thức tĩnh), hoặc ít nhất đó là những gì tôi đã được dẫn đến tin vào các tài liệu tôi đã đọc.
Núi lửa

21
@Vaccano: Một phương thức tĩnh có đầu ra hoặc ngoại lệ ngẫu nhiên có tác dụng phụ.
Tikhon Jelvis

10
@TikhonJelvis Robert đã nói về đầu ra; và ngoại lệ "ngẫu nhiên" không nên là tác dụng phụ, về cơ bản chúng là một dạng đầu ra. Vấn đề là, bất cứ khi nào bạn kiểm tra một phương thức gọi phương thức tĩnh, bạn sẽ gói phương thức đó và tất cả các hoán vị của đầu ra tiềm năng của nó và không thể kiểm tra phương thức của bạn một cách cô lập.
Nicole

26

Bạn dường như đang nhầm lẫn dữ liệu tĩnh và phương thức tĩnh . Chia sẻ lại, nếu tôi nhớ chính xác, khuyên bạn nên tạo privatecác phương thức trong một lớp tĩnh nếu chúng có thể được thực hiện - tôi tin rằng điều này mang lại lợi ích hiệu suất nhỏ. Nó không khuyên bạn nên làm "bất cứ điều gì có thể" tĩnh!

Không có gì sai với các phương thức tĩnh và chúng rất dễ kiểm tra (miễn là chúng không thay đổi bất kỳ dữ liệu tĩnh nào). Ví dụ, nghĩ về một thư viện Toán học, đây là ứng cử viên tốt cho một lớp tĩnh với các phương thức tĩnh. Nếu bạn có một phương thức (dự tính) như thế này:

public static long Square(int x)
{
    return x * x;
}

sau đó điều này là rõ ràng có thể kiểm tra và không có tác dụng phụ. Bạn chỉ cần kiểm tra xem khi bạn đi vào, giả sử, 20 bạn nhận lại 400. Không vấn đề gì.


4
Điều gì xảy ra khi bạn có một lớp khác gọi phương thức tĩnh này? Có vẻ đơn giản trong trường hợp này, nhưng nó là một phụ thuộc không thể tách rời trừ một trong ba công cụ được liệt kê ở trên. Nếu bạn không cô lập nó thì bạn không phải là "thử nghiệm đơn vị", bạn là "thử nghiệm tích hợp" (bởi vì bạn đang thử nghiệm các đơn vị khác nhau của bạn "tích hợp" với nhau như thế nào
Vaccano

3
Chẳng có gì xảy ra. Tại sao nó? .NET framework có đầy đủ các phương thức tĩnh. Bạn có nói rằng bạn không thể sử dụng chúng trong bất kỳ phương pháp nào bạn muốn kiểm tra đơn vị không?
Dan Diplo

3
Chà, nếu mã của bạn ở mức sản xuất / chất lượng của .NET Framework thì chắc chắn, hãy tiếp tục. Nhưng toàn bộ điểm của thử nghiệm đơn vị là thử nghiệm đơn vị, trong sự cô lập. Nếu bạn cũng đang gọi các phương thức trong các đơn vị khác (có thể là tĩnh hoặc khác) thì bây giờ bạn đang kiểm tra đơn vị của mình cộng với các phụ thuộc của nó. Tôi không nói rằng nó không phải là một thử nghiệm hữu ích, nhưng không phải là "thử nghiệm đơn vị" theo hầu hết các định nghĩa. (Bởi vì bạn hiện đang kiểm tra đơn vị dưới kiểm tra của mình và đơn vị có phương thức tĩnh).
Núi lửa

10
Có lẽ bạn (hoặc những người khác) đã thử nghiệm phương thức tĩnh và cho thấy rằng nó hoạt động (ít nhất là như mong đợi) trước khi viết quá nhiều mã xung quanh nó. Nếu có thứ gì đó bị hỏng trong phần bạn kiểm tra tiếp theo, đó là nơi bạn nên tìm trước, không phải trong phần bạn đã kiểm tra.
cHao

6
@Vaccano Vậy làm thế nào để Microsoft kiểm tra .NET Framework, sau đó, hả? Nhiều lớp trong Phương thức tĩnh tham chiếu khung trong các lớp khác (chẳng hạn như System.Math) không đề cập đến sự phong phú của các phương thức nhà máy tĩnh, v.v. Ngoài ra, bạn sẽ không bao giờ có thể sử dụng bất kỳ phương thức mở rộng nào, v.v. Thực tế là, các hàm đơn giản như thế này là cơ bản cho các ngôn ngữ hiện đại. Bạn có thể kiểm tra những thứ này một cách cô lập (vì chúng thường sẽ mang tính quyết định) và sau đó sử dụng chúng trong các lớp học của bạn mà không phải lo lắng. Nó không phải là vấn đề!
Dan Diplo

18

Nếu câu hỏi thực sự ở đây là "Làm cách nào để kiểm tra mã này?":

public class MyClass
{
   public void MethodToTest()
   {
       //... do something
       MyStaticClass.StaticMethod();
       //...more
   }
}

Sau đó, chỉ cần cấu trúc lại mã và thực hiện cuộc gọi đến lớp tĩnh như bình thường:

public class MyClass
{
   private readonly IExecutor _externalExecutor;
   public MyClass(_IExecutor executor)
   {
       _exeternalExecutor = executor;
   }

   public void MethodToTest()
   {
       //... do something
       _exetrnalExecutor.DoWork();
       //...more
   }
}

public class MyStaticClassExecutor : IExecutor
{
    public void DoWork()
    {
        MyStaticClass.StaticMethod();
    }
}

9
May mắn thay, chúng tôi cũng có câu hỏi về khả năng đọc mã và KISS trên SO quá :)
gbjbaanb

một đại biểu sẽ không dễ dàng hơn và làm điều tương tự?
jk.

@jk có thể, nhưng thật khó để sử dụng container IoC.
Nắng

15

Statics không nhất thiết là xấu, nhưng chúng có thể giới hạn các lựa chọn của bạn khi thử nghiệm đơn vị với hàng giả / giả / cuống.

Có hai cách tiếp cận chung để chế giễu.

Cái đầu tiên (truyền thống - được thực hiện bởi RhinoMocks, Moq, NMock2; giả và cùi thủ công cũng ở trong trại này) cũng dựa vào các đường nối thử nghiệm và tiêm phụ thuộc. Giả sử bạn đang kiểm tra đơn vị một số mã tĩnh và nó có phụ thuộc. Điều thường xảy ra trong mã được thiết kế theo cách này là statics tạo ra sự phụ thuộc của riêng họ, đảo ngược sự phụ thuộc đảo ngược . Bạn sớm phát hiện ra rằng bạn không thể đưa các giao diện giả vào mã theo thử nghiệm được thiết kế theo cách này.

Cái thứ hai (giả định bất cứ thứ gì - được TypeMock, JustMock và Moles thực hiện) dựa trên API Profiling của .NET . Nó có thể chặn bất kỳ hướng dẫn CIL nào của bạn và thay thế một đoạn mã của bạn bằng mã giả. Điều này cho phép TypeMock và các sản phẩm khác trong trại này chế giễu bất cứ điều gì: thống kê, lớp niêm phong, phương pháp riêng tư - những thứ không được thiết kế để có thể kiểm tra được.

Có một cuộc tranh luận đang diễn ra giữa hai trường phái tư tưởng. Một người nói, tuân theo các nguyên tắc và thiết kế RẮN để kiểm tra (thường bao gồm việc dễ dàng trong việc thống kê). Một người khác nói, hãy mua TypeMock và đừng lo lắng.


14

Kiểm tra điều này: "Phương pháp tĩnh là cái chết đối với khả năng kiểm tra " . Tóm tắt ngắn về đối số:

Để kiểm tra đơn vị, bạn cần lấy một đoạn mã nhỏ, viết lại các phụ thuộc của nó và kiểm tra nó một cách riêng lẻ. Điều này thật khó với các phương thức tĩnh, không chỉ trong trường hợp họ truy cập trạng thái toàn cầu mà ngay cả khi họ chỉ gọi các phương thức tĩnh khác.


32
Tôi không giữ trạng thái toàn cầu hoặc gây ra tác dụng phụ trong các phương thức tĩnh của mình, vì vậy lập luận này có vẻ không liên quan đến tôi. Bài viết mà bạn liên kết tạo ra một đối số độ dốc trơn trượt không có cơ sở nếu các phương thức tĩnh được giới hạn trong mã thủ tục đơn giản, hoạt động theo cách "chung" (như các hàm toán học).
Robert Harvey

4
@Robert Harvey - làm thế nào để bạn kiểm tra một phương thức sử dụng một phương thức tĩnh từ một lớp khác (tức là nó có một sự phụ thuộc vào một phương thức tĩnh). Nếu bạn chỉ để nó gọi nó thì bạn không phải là "thử nghiệm đơn vị" mà bạn là "thử nghiệm tích hợp"
Vaccano

10
Đừng chỉ đọc bài viết trên blog, hãy đọc nhiều bình luận không đồng ý với nó. Một blog chỉ là một ý kiến, không phải là một thực tế.
Dan Diplo

8
@Vaccano: Một phương thức tĩnh không có tác dụng phụ hoặc trạng thái bên ngoài tương đương về mặt chức năng với một giá trị. Biết rằng, nó không khác gì đơn vị kiểm tra một phương thức tạo ra một số nguyên. Đây là một trong những hiểu biết quan trọng mà lập trình chức năng mang lại cho chúng ta.
Steven Evers

3
Việc chặn các hệ thống nhúng hoạt động hoặc một ứng dụng có lỗi có khả năng tạo ra các sự cố quốc tế, IMO, khi "khả năng kiểm tra" điều khiển kiến ​​trúc, bạn đã vặn nó trước khi bạn áp dụng các phương pháp thử nghiệm ở mọi góc cuối cùng. Ngoài ra, tôi mệt mỏi với phiên bản XP của mọi thứ chi phối mọi cuộc trò chuyện. XP không phải là một cơ quan có thẩm quyền, nó là một ngành công nghiệp. Đây là định nghĩa ban đầu, hợp lý của thử nghiệm đơn vị: python.net/crew/tbryan/UnitTestTalk/slide2.html
Erik

5

Một sự thật đơn giản hiếm khi được thừa nhận là nếu một lớp chứa một phụ thuộc có thể nhìn thấy của trình biên dịch trên một lớp khác, thì nó không thể được kiểm tra tách biệt với lớp đó. Bạn có thể giả mạo một cái gì đó trông giống như một bài kiểm tra và sẽ xuất hiện trên một báo cáo như thể đó là một bài kiểm tra.

Nhưng nó sẽ không có các thuộc tính xác định chính của một bài kiểm tra; thất bại khi mọi thứ sai, vượt qua khi họ đúng.

Điều này áp dụng cho bất kỳ cuộc gọi tĩnh, cuộc gọi hàm tạo và bất kỳ tham chiếu nào đến các phương thức hoặc trường không được kế thừa từ một lớp cơ sở hoặc giao diện . Nếu tên lớp xuất hiện trong mã, thì đó là một phụ thuộc có thể nhìn thấy của trình biên dịch và bạn không thể kiểm tra hợp lệ nếu không có nó. Bất kỳ khối nhỏ hơn chỉ đơn giản là không phải là một đơn vị kiểm tra hợp lệ . Bất kỳ nỗ lực nào để coi nó như thể nó sẽ có kết quả không có ý nghĩa hơn việc viết một tiện ích nhỏ để phát ra XML được sử dụng bởi khung kiểm tra của bạn để nói 'thử nghiệm đã qua'.

Cho rằng, có ba lựa chọn:

  1. định nghĩa kiểm thử đơn vị là kiểm thử đơn vị gồm một lớp và nó phụ thuộc mã hóa cứng. Điều này hoạt động, cung cấp cho bạn tránh phụ thuộc tròn.

  2. không bao giờ tạo các phụ thuộc thời gian biên dịch giữa các lớp bạn chịu trách nhiệm kiểm tra. Điều này hoạt động, cung cấp cho bạn không quan tâm đến kiểu mã kết quả.

  3. không kiểm tra đơn vị, kiểm tra tích hợp thay thế. Cái nào hoạt động, cung cấp nó không xung đột với cái gì khác mà bạn cần để sử dụng thuật ngữ kiểm tra tích hợp.


3
Không có gì nói rằng một bài kiểm tra đơn vị là một bài kiểm tra của một lớp duy nhất. Đó là một thử nghiệm của một đơn vị. Các thuộc tính xác định của các bài kiểm tra đơn vị là chúng nhanh, lặp lại và độc lập. Tham chiếu Math.Pitrong một phương pháp không làm cho nó trở thành một thử nghiệm tích hợp theo bất kỳ định nghĩa hợp lý nào.
sara

tức là tùy chọn 1. Tôi đồng ý rằng đó là cách tiếp cận tốt nhất, nhưng có thể hữu ích khi biết người khác sử dụng các thuật ngữ khác nhau (hợp lý hay không).
soru

4

Không có hai cách về nó. Các đề xuất của ReSharper và một số tính năng hữu ích của C # sẽ không được sử dụng thường xuyên nếu bạn đang viết các bài kiểm tra đơn vị nguyên tử bị cô lập cho tất cả mã của mình.

Ví dụ, nếu bạn có một phương thức tĩnh và bạn cần loại bỏ nó, bạn không thể trừ khi bạn sử dụng khung cách ly dựa trên hồ sơ. Cách giải quyết tương thích với cuộc gọi là thay đổi đỉnh của phương thức để sử dụng ký hiệu lambda. Ví dụ:

TRƯỚC:

    public static DBConnection ConnectToDB( string dbName, string connectionInfo ) {
    }

SAU:

    public static Func<string, string, DBConnection> ConnectToDB (dbName, connectionInfo ) {
    };

Hai là tương thích cuộc gọi. Người gọi không phải thay đổi. Cơ thể của chức năng vẫn giữ nguyên.

Sau đó, trong mã Kiểm tra đơn vị của bạn, bạn có thể thực hiện cuộc gọi này như vậy (giả sử đó là trong một lớp có tên là Cơ sở dữ liệu):

        Database.ConnectToDB = (dbName, connectionInfo) => { return null|whatever; }

Hãy cẩn thận để thay thế nó bằng giá trị ban đầu sau khi bạn hoàn thành. Bạn có thể thực hiện điều đó thông qua một lần thử / cuối cùng hoặc, trong phần kiểm tra đơn vị của bạn, phần được gọi sau mỗi bài kiểm tra, viết mã như thế này:

    [TestCleanup]
    public void Cleanup()
    {
        typeof(Database).TypeInitializer.Invoke(null, null);
    }

cái này sẽ gọi lại bộ khởi tạo tĩnh của lớp bạn.

Lambda Funcs không hỗ trợ nhiều như các phương thức tĩnh thông thường, vì vậy phương pháp này có các tác dụng phụ không mong muốn sau:

  1. Nếu phương thức tĩnh là phương thức mở rộng, trước tiên bạn phải thay đổi nó thành phương thức không mở rộng. Resharper có thể làm điều này cho bạn tự động.
  2. Nếu bất kỳ kiểu dữ liệu nào của các phương thức tĩnh là một tổ hợp xen kẽ nhúng, chẳng hạn như đối với Office, bạn phải bọc phương thức, bọc kiểu hoặc thay đổi thành kiểu 'đối tượng'.
  3. Bạn không còn có thể sử dụng công cụ tái cấu trúc chữ ký thay đổi của Resharper.

Nhưng hãy nói rằng bạn tránh hoàn toàn thống kê và bạn chuyển đổi nó thành một phương thức cá thể. Nó vẫn không thể bị nhạo báng trừ khi phương thức này là ảo hoặc được triển khai như một phần của giao diện.

Vì vậy, trong thực tế, bất cứ ai đề xuất biện pháp khắc phục các phương thức tĩnh là biến chúng thành các phương thức cá thể, chúng cũng sẽ chống lại các phương thức cá thể không phải là ảo hoặc là một phần của giao diện.

Vậy tại sao C # có phương thức tĩnh? Tại sao nó cho phép các phương thức cá thể không ảo?

Nếu bạn sử dụng một trong hai "Tính năng" này, thì đơn giản là bạn không thể tạo các phương thức bị cô lập.

Vậy khi nào bạn sử dụng chúng?

Sử dụng chúng cho bất kỳ mã nào mà bạn không mong đợi bất kỳ ai muốn khai thác. Một số ví dụ: phương thức Format () của lớp String, phương thức WriteLine () của lớp Console, phương thức Cosh () của lớp Math

Và một điều nữa .. Hầu hết mọi người sẽ không quan tâm đến điều này, nhưng nếu bạn có thể về hiệu suất của một cuộc gọi gián tiếp, đó là một lý do khác để tránh các phương thức cá thể. Có những trường hợp khi đó là một hiệu suất hit. Đó là lý do tại sao các phương thức không ảo tồn tại ở nơi đầu tiên.


3
  1. Tôi tin rằng một phần vì các phương thức tĩnh "gọi" nhanh hơn các phương thức cá thể. (Trong dấu ngoặc kép vì mùi này tối ưu hóa vi mô) xem http://dotnetperls.com/static-method
  2. Nó nói với bạn rằng nó không cần trạng thái, do đó có thể được gọi từ bất cứ đâu, loại bỏ chi phí xúi giục nếu đó là điều duy nhất ai đó cần.
  3. Nếu tôi muốn chế giễu nó, thì tôi nghĩ đó thường là cách thực hành mà nó đã tuyên bố trên một giao diện.
  4. Nếu nó được khai báo trên một giao diện thì R # sẽ không đề nghị bạn làm cho nó tĩnh.
  5. Nếu nó được khai báo là ảo, thì R # sẽ không đề nghị bạn làm cho nó tĩnh.
  6. Giữ trạng thái (trường) tĩnh là điều cần luôn được xem xét cẩn thận . Trạng thái tĩnh và chủ đề trộn như lithium và nước.

R # không phải là công cụ duy nhất sẽ đưa ra gợi ý này. Phân tích mã FxCop / MS cũng sẽ làm tương tự.

Tôi thường nói rằng nếu phương thức là tĩnh, nói chung nó cũng có thể kiểm tra được. Điều đó mang lại một số cân nhắc về thiết kế và có lẽ là thảo luận nhiều hơn những gì tôi có trong ngón tay của mình ngay bây giờ, vì vậy hãy kiên nhẫn chờ đợi những phiếu bầu và bình luận ...;)


Bạn có thể khai báo một phương thức / đối tượng tĩnh trên một giao diện không? (Tôi không nghĩ vậy). Cách Ether, tôi đang đề cập đến khi phương thức tĩnh của bạn được gọi bằng phương thức được thử nghiệm. Nếu người gọi ở một đơn vị khác thì phương thức tĩnh cần được cách ly. Điều này rất khó thực hiện với một trong ba công cụ được liệt kê ở trên.
Núi lửa

1
Không, bạn không thể khai báo tĩnh trên giao diện. Nó sẽ là vô nghĩa.
MIA

3

Tôi thấy rằng sau một thời gian dài, không ai nói ra một sự thật đơn giản. Nếu resharper nói với tôi rằng tôi có thể làm cho một phương thức tĩnh, nó có nghĩa là một điều rất lớn đối với tôi, tôi có thể nghe giọng nói của anh ấy nói với tôi: "này, bạn, những mảnh logic này không phải là TRÁCH NHIỆM của lớp hiện tại để xử lý, vì vậy nó nên tránh xa trong một số lớp người trợ giúp hoặc một cái gì đó ".


2
Tôi không đồng ý. Hầu hết thời gian khi Resharper nói rằng tôi có thể tạo ra một cái gì đó tĩnh, đó là một ít mã phổ biến cho hai hoặc nhiều phương thức trong lớp và do đó tôi đã trích xuất nó ra thủ tục riêng của nó. Chuyển nó đến một người trợ giúp sẽ là vô nghĩa phức tạp.
Loren Pechtel

2
Tôi chỉ có thể thấy quan điểm của bạn nếu tên miền rất đơn giản và nó không phù hợp để sửa đổi trong tương lai. Một cách khác biệt, cái mà bạn gọi là "sự phức tạp vô nghĩa" đó là thiết kế tốt và dễ đọc với con người. Có một lớp người trợ giúp với lý do đơn giản và rõ ràng để tồn tại theo một cách nào đó là "thần chú" của các nguyên tắc SoC và Trách nhiệm duy nhất. Ngoài ra, xem xét rằng lớp mới này trở thành một sự phụ thuộc cho lớp chính, nó phải phơi bày một số thành viên công cộng, và do đó, nó trở nên có thể kiểm chứng một cách cô lập và dễ bị chế giễu khi hoạt động như một sự phụ thuộc.
g1ga

1
Không liên quan đến câu hỏi.
Igby Largeeman

2

Nếu phương thức tĩnh được gọi từ bên trong phương thức khác , không thể ngăn chặn hoặc thay thế một cuộc gọi như vậy. Điều này có nghĩa, hai phương thức này tạo thành một Đơn vị duy nhất; Kiểm tra đơn vị của bất kỳ loại kiểm tra cả hai.

Và nếu phương thức tĩnh này nói chuyện với Internet, kết nối cơ sở dữ liệu, hiển thị cửa sổ bật lên GUI hoặc chuyển đổi kiểm tra Đơn vị thành mớ hỗn độn, thì nó chỉ thực hiện mà không có bất kỳ công việc dễ dàng nào xung quanh. Một phương thức gọi phương thức tĩnh như vậy không thể kiểm tra được nếu không tái cấu trúc, ngay cả khi nó có rất nhiều mã tính toán thuần túy sẽ có lợi rất cao từ việc được kiểm tra đơn vị.


0

Tôi tin rằng Resharper đang cung cấp cho bạn thông tin và áp dụng các nguyên tắc mã hóa mà nó đã được thiết lập. Khi tôi đã sử dụng Resharper và nó đã nói với tôi rằng một phương thức nên tĩnh, nó nhất định là một phương thức riêng không hoạt động trên bất kỳ biến đối tượng nào.

Bây giờ, đối với khả năng kiểm tra, kịch bản này không phải là một vấn đề vì dù sao bạn cũng không nên thử nghiệm các phương thức riêng tư.

Đối với khả năng kiểm tra của các phương thức tĩnh là công khai thì kiểm thử đơn vị sẽ trở nên khó khăn khi các phương thức tĩnh chạm vào trạng thái tĩnh. Cá nhân tôi sẽ giữ điều này ở mức tối thiểu và sử dụng các phương thức tĩnh càng nhiều hàm càng tốt khi có bất kỳ sự phụ thuộc nào được truyền vào phương thức có thể được điều khiển thông qua một vật cố thử nghiệm. Tuy nhiên đây là một quyết định thiết kế.


Tôi đang đề cập đến khi bạn có một phương thức đang thử nghiệm (không phải tĩnh) gọi một phương thức tĩnh trong một lớp khác. Sự phụ thuộc đó chỉ có thể được phân lập bằng một trong ba công cụ được liệt kê ở trên. Nếu bạn không cô lập nó thì bạn đang thử nghiệm tích hợp, không phải thử nghiệm đơn vị.
Vaccano

Truy cập các biến đối tượng vốn có nghĩa là nó không thể tĩnh. Trạng thái duy nhất mà một phương thức tĩnh có thể có là các biến lớp và lý do duy nhất sẽ xảy ra là nếu bạn đang xử lý một singleton và do đó không có lựa chọn nào.
Loren Pechtel
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.