2012-03-19 2 views
0

은 내가 그러나 내가 DisplayError가 null의 경우에 예외를 던진 것으로 볼 수 DisplayError을 호출 할이 방법에 Action<string>TDD 및 디자인 조언

public Action<string> DisplayError; 

public void MyMethod() 
{ 
    DisplayError("ERROR"); 
} 

를 호출하는 방법이있다.

예외가 발생한다는 것을 증명하는 테스트를 실행할 수 있습니다.

그래서 코드에 if (DisplayError != null)을 추가하려고하지만이 디자인이 어떻게 든 잘못되었다고 생각합니다. 테스트가 달라야할까요?

+0

가능하면 null을 전달/반환하지 마십시오. 이 경우 DisplayError를 호출 할 때 아무 것도 수행하지 않는 No-Op 액션을 기본값으로 설정할 수 있습니다. 증상과 같은 깨진 창으로, 첫 번째 null-check은 null-checks가 모든 곳에서 버섯을 만들기 시작하도록합니다. Null 참조 예외는 무언가 잘못되어 라이브러리를 사용하는 방법에 대한 디자인 또는 인식 개선을 통해 즉시 수정되어야 함을 의미합니다. – Gishu

답변

1

Action을 public 필드로 설정하는 대신 속성으로 만들거나 메서드에 전달하십시오. 그 시점에서 널 검사를 할 수 있습니다. 나는 또한 당신이 그것을 설정 한 후이를 검색 할 필요가 있다고 의심, 그래서 다음 중 하나를

_displayError = (s) => { throw new ArgumentNullException("Please tell me what to do with this exception!"); }; 

public Action<string> DisplayError 
{ 
    set 
    { 
     if (value == null) { throw new ArgumentNullException("I need this!"); } 
     _displayError = value; 
    } 
} 

public void MyMethod() 
{ 
    _displayError("ERROR"); 
} 

또는 :

public void MyMethod(Action<string> displayError) 
{ 
    if (displayError == null) { throw new ArgumentNullException("I need this!"); } 
    displayError("ERROR"); 
} 

하여 소비자의 코드를 변경 할 필요가 없습니다이 중 첫 번째.

물론 코드를 사용하는 팀원과 함께 작업하는 경우 은 null 체크를 전혀하지 않아도됩니다.. 당신의 코드를 잘못 사용하고있는 사람을 찾아서 오해가있는 곳에서 우호적 인 대화를 나누십시오. 방어 프로그래밍은 회원들이 서로를 신뢰하는 팀을 대체 할 수있는 좋은 대안이 아니며, 널 검사는 명확하고 정의 된 인터페이스를 사용하는 것만 큼 효과적이지 못합니다.

당신은이 개 테스트가 필요합니다

내 클래스 :

  • 은 소비자가 오류를
    • 나는 어떤 이유에서 오류가 발생거야 감안할 때 (세트를 처리 할 수 ​​있도록해야 context here)
    • 오류가 발생하면 (오류 처리기에서 변수를 설정하도록)
    • 그러면 처리기에 오류를 제공해야합니다 오류 처리기가 연결되어 있는지 확인해야합니다
  • (설정있어 변수를 확인)
    • 내가
    • 때 소비자 (는 무관 때문에 당신이 여기에 좋아하는 것을 코딩 할 수 있습니다) 오류가 발생 할 수 감안할 때
    • 그런 다음 내가 바로 그렇게하지 않는 소비자를 요청해야 오류 처리기 (null 오류 핸들러 메서드 호출)없이 저를 호출
,369 (예외 확인)
+0

후자의 옵션을 사용했지만 테스트에 표시해야 할 내용이 확실하지 않습니다. – Jon

+0

업데이트 됨. 그 "shoulds"다음에 테스트의 이름을 지정하고, "Given, When, Then"을 주석에 넣고 갭을 채우십시오. – Lunivore

0

스티브 예지 (Steve Yeggie)와의 인터뷰에서 나는 정적 인 유형의 언어가 컴파일 타임에 다양한 종류의 오류로부터 당신을 보호하고 있지만, 널 확인을 위해. '

나는 이것이 정상적으로 발견됩니다.

나는 아침 커피를 마시고 있기 때문에 마크를 완전히 놓친 경우 알려 주시기 바랍니다.

+0

nulls를 확인하기 위해 코드를 추가해야한다는 것을 알고 있지만 테스트 또는 뭔가가 제대로 작동하지 않는다고 생각합니다. null을 던지는 액션을 할당하지 않으면 테스트가 실행됩니까? 아니면 테스트가 할당 된 시점을 보여주는 테스트를 수행합니까? – Jon

+0

나는 액션이 ​​null 일 가능성이 문제라고 생각한다면 테스트를 추가하는 것이 정당하다고 생각합니다. 생산이 끝나고 그로 인해 실패하면 나중에 차버릴 것입니다. – dwerner

1

전적으로 상황에 따라 다릅니다.

이 클래스의 사용자는 이 필요합니다 계약을 기반으로 값을 설정하려면? 그런 다음 예외가 발생합니다.

선택 사항입니까? 그런 다음 검사는 유효하지만 당신은 단지 빈 작업에 DisplayError 기본, 당신은 비슷한 동작을 얻을 것이다

DisplayError = s => {}; 

귀하의 접근 방식은 또한 사용자가DisplayErrornull에 그 경우에 설정 수있는 가능성에 이르게 , 당신 만이 무엇이 유효한 것인지 결정할 수 있습니다. 필드 대신 속성을 설정하면 더 많은 옵션을 제공합니다.

_displayError = s => {}; 

public Action<string> DisplayError 
{ 
    get { return _displayError; } 
    set 
    { 
     _displayError = value ?? (s => {}); 
     /* or throw on null */ 
    } 
} 
+0

클래스에 Windows 폼 컨트롤이 있고이 작업과 동일한 폼 (GUI 업데이트)에 루틴을 할당한다고 생각했습니다. 현재 폼 구현이 존재하지 않고이 메소드/액션을 테스트하고 있습니다. – Jon

+0

@Jon 여러분이나 팀원이 GUI를 업데이트하는 폼을 담당한다면 누구도 클래스를 호출하지 않는 것이 좋습니다. 그 안에 null 체크를 넣는 것보다 널을 가진. 프로덕션 환경에서 사용되지 않는 것들을 프로그램하지 마십시오. 단지 유지 보수를 악몽으로 만듭니다. – Lunivore

+0

@ 존 : 컨트롤이 필요한 인터페이스를 구현합니까? –