2013-08-13 1 views
2

자, 저는 CIRCLE이라는 클래스와 SQUARE라는 클래스가 있다고 가정 해 봅시다. 각 클래스에는 area라는 공용 함수가 있습니다. (원의 면적이 이고 정사각형의 면적이 각각입니다.)VB.NET에서 TDD에 대한 매우 복잡한 객체를 가짜로 만드는 방법

나는 또한 iMath 클래스가 있습니다. 이 클래스에서, 나는 함수가

Public Function ADD(byval c as CIRCLE, byval s as SQUARE) 
     Return c.area() + s.area() 
    End Function 

지금 내가 단위 테스트에 추가 기능을 원하는 ADD 있습니다. 분명히이 매우 쉬운 문제에 대해 Unit 테스트에서 ADD 기능을 테스트 할 때 circle 객체와 square 객체를 쉽게 만들 수 있습니다. 그러나 내 서클 개체 및 사각형 개체를 상속하고 많은 다른 종속성이 포함되어 있기 때문에 매우 복잡한 개체, 개체를 만드는 것은 매우 어렵다고 가정하십시오. 이 경우

  1. 원 및 원추체를 어떻게 위조 할 수 있습니까? (주 : CIRCLE 및 SQUARE 클래스에는 매개 변수가없는 Public Sub New가 없습니다.)

  2. 면적 함수의 결과를 원형 및 사각형 개체로 가짜 만드는 방법은 무엇입니까? 기능을 추가하고, 당신이 CIRCLESQUARE 클래스 Overridable의 모든 구성원을하면 그때 당신이 그들을 상속 스텁 모든 구성원을 대체 할 수 있습니다,

답변

2

) 영역을 계산하는 방법을 상관 없어, 예 :

Public Class Circle 
    Public Overridable Function Area() As Integer 
     ' Complicated logic 
    End Function 
End Class 

Public Class MockCircle 
    Inherits Circle 

    Public Overrides Function Area() As Integer 
     Return 10 
    End Function 
End Class 

그러나 원래 CIRCLE 클래스가 생성자에서 생성하기 어려운 매개 변수를 필요로하는 경우 MockCircle 클래스가 기본 생성자를 호출해야하므로 필요하지 않습니다.

인터페이스를 사용하는 것이 가장 좋은 해결책입니다. 촬영 한 때문에이 CIRCLE는 생성자에서 필요로 중요하지 않습니다, 지금

Public Interface ICircle 
    Function Area() As Integer 
End Interface 

Public Class Circle 
    Implements ICircle 

    Public Function Area() As Integer Implements ICircle.Area 
     ' Complicated logic 
    End Function 
End Class 

Public Class MockCircle 
    Implements ICircle 

    Public Function Area() As Integer Implements ICircle.Area 
     Return 10 
    End Function 
End Class 

Public Class MyMath 
    Public Function Add(c As ICircle, s As ISquare) As Integer 
     Return c.Area() + s.Area() 
    End Function 
End Class 

대신 당신의 ADD 방법은 콘크리트 CIRCLE 객체를 받아 들일 필요없이이 대신 ICircle 인터페이스를 구현하는 객체를 요청해야 그것은 방정식에서 완전히 벗어났다. 이제 ADD 메서드에 CIRCLE 개체 또는 MockCircle 개체를 지정하면 어느 쪽이든 작동합니다. MockCircle 개체는 CIRCLE에서 상속되지 않으므로 복잡한 종속성을 공유하지 않습니다. 이 방법론에는 실제로도 편리한 이름이 있습니다. 그것은 Dependency Injection (DI)입니다. 단위 테스트를 많이하려면 DI에 대한 조사를 해 보는 것이 좋습니다. 이상적으로는 CIRCLE 클래스의 종속성도 모두 인터페이스를 통해 이루어 지므로 CIRCLE 객체도 종속성에 대한 모든 모의 객체를 제공하여 쉽게 만들 수 있습니다.

나는 코드에 표면적 인 문제점에 대해서 언급해야 할 의무가있다. .NET Framework 및 Microsoft 표준과의 일관성을 유지하려면 모든 메서드 및 클래스 이름에 PascalCase를 사용해야합니다. 예를 들어 ADD 대신 Add이어야하며 CIRCLESQUARE 대신 CircleSquare이어야합니다. 또한 iMath 클래스 이름은 문자 "i"로 시작하면 안됩니다.Microsoft 표준에 따라 형식 이름의 시작 부분에 "I"를 붙이면 클래스가 아니라 인터페이스라는 것을 의미합니다. 마지막으로 본 문제는 ADD 함수가 반환 형식을 지정하지 않는다는 것입니다. 모든 함수에 대해 항상 반환 유형을 지정해야합니다. 예를 들어, 나의 예에서는 As Integer을 반환하도록 변경했습니다.

+1

코딩 스타일에 대한 조언을 해주신 스티븐에게 감사드립니다. 그것은 매우 유용합니다. TDD에 관해서, 내가 Unit에서 모든 기능을 테스트하고 싶다면, MyMath Class가 당신의 조언에서 말하길, 내가 가지고있는 모든 기능을위한 인터페이스를 만들어야한다는 것을 암시하고 있습니까? –

+1

예, 단위 테스트를하는 경우 모든 공용 메소드가 노출되어 하나 이상의 인터페이스를 통해 사용되면 * 쉽게 * 쉽습니다. 그렇게하지 않으면 테스트를 위해 모의 객체를 구현하는 것이 훨씬 더 어려워 질 것입니다. 단위 테스트의 모든 장점 외에도 인터페이스를 통한 DI에는 많은 다른 장점이 있습니다. 예를 들어 코드가 좀 더 유연하고 깨끗하며 확장 성이 뛰어나고 버그가 적고 유지 보수가 쉽고 리팩터링하는 등의 작업을 수행 할 수 있습니다. 더 많은 예제와 소개가 필요하면 다른 기사를 읽어보십시오. 주제에 대한 깊이있는 대답. –

+0

[Windows 서비스 및 ASP.NET에서 DLL 로깅] (http://stackoverflow.com/a/13636961/1359668). [BLL (Business Logic Layer)을 BLL 및 DAL (Data Access Layer)로 분할] (http://stackoverflow.com/a/14112902/1359668). [VB.NET 클래스 또는 모듈의 목적은 무엇입니까] (http://stackoverflow.com/a/14086535/1359668) (특히 ** 코드에서 솔기 제공 **). [ "팬시 팬츠"대 "카우보이"코딩 ​​(http://codereview.stackexchange.com/a/29025/22613) –

1

기존의 조롱 프레임 워크에 의존해야합니다.이 문제를 정확하게 해결해야합니다. 내가 가장 좋아하는 책은 NSubsitute입니다.

가상 함수가있는 클래스의 모든 인터페이스에 모의 객체를 만들 수 있습니다. 그리고 일반적으로 수동 mock을 만드는 것이 더 바람직합니다.

관련 문제