2010-08-17 5 views
5

필자는 지난 몇 년 동안 self-shunt unit 테스트 패턴을 몇 번 사용했습니다. 최근에 누군가에게 설명 했으므로 그들은 SRP를 위반했다고 주장했습니다. 논쟁은 이제 테스트 클래스가 테스트가 변경 될 때 또는 테스트가 구현하는 인터페이스의 메소드 서명이 변경 될 때 변경 될 수 있다는 것입니다. 잠시 생각해 본 결과 올바른 평가라고 생각되지만 다른 사람들의 의견을 듣고 싶었습니다. 생각?셀프 션트 테스트 패턴이 Single Responsibility Principle을 위반합니까?

참조 : 인터페이스가 구현 또는 분로되는 경우 http://www.objectmentor.com/resources/articles/SelfShunPtrn.pdf

답변

5

제 생각에는 테스트 클래스가 기술적으로 SRP를 위반하지만 SRP의 정신을 위반하지 않습니다. self-shunting의 대안은 모의 클래스를 테스트 클래스와 분리시키는 것이다.

별도의 mock 클래스를 사용하면 자체 포함되어 있으며 SRP를 만족한다고 생각할 수 있지만 mock 클래스의 속성에 대한 의미 적 결합은 여전히 ​​존재합니다. 그래서, 정말로, 우리는 의미있는 분리를 이루지 못했습니다.

PDF 파일에서 예를 촬영 :

public class ScannerTest extends TestCase implements Display 
{ 
    public ScannerTest (String name) { 
    super (name); 
    } 
    public void testScan() { 
    // pass self as a display 
    Scanner scanner = new Scanner (this); 
    // scan calls displayItem on its display 
    scanner.scan(); 
    assertEquals (new Item (“Cornflakes”), lastItem); 
    } 
    // impl. of Display.displayItem() 
    void displayItem (Item item) { 
    lastItem = item; 
    } 
    private Item lastItem; 
} 

지금 우리가 만드는 모의 : 실질적으로 (IMHO) DisplayMockTestClass의 높은 커플 링에서

public class DisplayMock implements Display 
{ 
    // impl. of Display.displayItem() 
    void displayItem (Item item) { 
    lastItem = item; 
    } 

    public Item getItem() { 
    return lastItem; 
    } 
    private Item lastItem; 
} 

public class ScannerTest extends TestCase 
{ 
    public ScannerTest (String name) { 
    super (name); 
    } 
    public void testScan() { 
    // pass self as a display 
    DisplayMock dispMock = new DisplayMock(); 
    Scanner scanner = new Scanner (dispMock); 
    // scan calls displayItem on its display 
    scanner.scan(); 
    assertEquals (new Item (“Cornflakes”), dispMock.GetItem()); 
    } 
} 

보다 더 큰 악 TestClass에 대한 SRP의 위반. 게다가, 조롱 프레임 워크를 사용하면이 문제는 완전히 사라집니다.

EDIT 로버트 C. 마틴의 훌륭한 서적 Agile Principles, Patterns, and Practices in C#에서 자기 분지 패턴에 대한 간략한 언급이 있습니다.

alt text

그래서 (같은 책에서 훌륭한 세부 사항에 대해 이야기한다)을 SRP를 만들어 낸 사람이 자기 션트 패턴을 사용하여 양심의 가책이 없습니다 다음은 책의 밖으로 조각입니다. 그렇다면이 패턴을 사용할 때 당신이 OOP (Orientated Police)로부터 꽤 안전하다고 말할 수 있습니다.

1

이 테스트 스위트뿐만 아니라 변경해야 할 것입니다 상대적으로 가능성, 변경됩니다. 그래서 나는 그것을 SRP 위반으로 보지는 않습니다.

+0

분명히 좋은 지적이지만 잘못된 주장입니다. 테스트가 어쨌든 변경 될 가능성이 있기 때문에이 패턴을 사용하더라도 테스트 클래스가 SRP를 위반하지 않는다는 의미는 아닙니다. 실용적인 견지에서 볼 때, 나는 그 패턴을 사용하고 아마도 SRP를 위반하지 않을 것이라고 말했습니다. –

1

나는 내가 만들고있는 mocks/stubs를 좀 더 제어 할 것을 선호합니다. 셀프 션트 패턴을 사용해 보았을 때 테스트 클래스를 좀 더 복잡하게 만들었습니다. 테스트 메소드 내에서 모의 ​​객체를 만들어서 코드를 깨끗하게 만들었습니다.

FWIW C# (또는 파이썬 또는 이와 동등한 것)과 같은 강력한 기능을 사용하지 않으면 인터페이스를 변경할 때 테스트 코드가 변경됩니다.

3

제 의견으로는 이며 위반 사항은 매우 미약합니다.

테스트 클래스는 현재 테스트 클래스 테스트 클래스입니다.

그러나 나쁜 것입니까? 몇 가지 간단한 테스트를 위해서는 아마도 그렇지 않을 수도 있습니다.테스트 사례 수가 늘어남에 따라 리팩토링하고 모의 수업을 사용하여 문제의 일부를 분리해야 할 수 있습니다. (붙여 넣은 링크가 말했듯이, 셀프 션트 (self-shunt)는 조롱하는 디딤돌입니다.) 그러나 테스트 케이스의 수가 정적이거나 낮다면 문제는 무엇입니까?

약간의 실용주의가 필요하다고 생각합니다. SRP를 위반합니까? 네,하지만 테스트하고있는 시스템의 코드 중 일부는 아닐 것입니다. 그것에 대해 아무 것도해야합니까? 아니요, 코드가 명확하고 유지 관리가 가능한 한 오랫동안 아닙니다. 저에게있어 항상 핵심적인 부분입니다. SRP는 지침이 아닌 규칙입니다.

+0

글쎄. 다른 의견에 암시했듯이, 나는 그것을 사용하는 것에 반대하지 않지만 SRP를 "기술적으로"위반한다는 검증을 원했습니다. –

관련 문제