2011-11-29 2 views
1

Moles를 사용하여 IsHappy 함수를 테스트하려면 어떻게해야합니까?Moles를 사용하여 가상 메서드를 테스트하는 방법은 무엇입니까?

SSomeClass stub = new SSomeClass(); 
stub.CallBase = true; 
Assert.IsTrue(stub.IsHappyString("Happy")); 

을 ...하지만 IsHappyString 메소드가 반환 따라서 NullReference 예외를 던지는 null로 :

class SomeClass 
{ 
    protected virtual bool IsHappy(string mood) 
    { 
      return (mood == "Happy"); 
    } 
} 

나는 스텁을 사용하여 경우를 테스트하기 위해 노력했다.

따라서 IsHappy 메서드의 기본 구현을 테스트하려면 어떻게해야합니까?

답변

1

스텁 및 Moles는 클래스가 환경 의존성 또는 클래스 종속성과 관련된 종속성에서 클래스를 분리하기위한 것입니다. 이 클래스는 아무런 의존성이 없으므로, 왜 그것을 두더지 또는 스텁하려고합니까?

사람들이이 기본 클래스를 재정의 할 때 제대로 작동하게하려면 테스트 구현을 만들어야합니다. 이 경우이 테스트 케이스가 어떻게 보일지 더 많거나 적은이다.

public SomeClassTestAdapter : SomeClass 
{ 
    public bool GetIsHappy(string mood) 
    { 
     return IsHappy(mood); 
    } 
} 

[Test] 
public void ShouldReturnTrueWhenPassedHappy() 
{ 
    var classUnderTest = new SomeClassTestAdapter(); 
    bool result = classUnderTest.IsHappy("Happy"); 
    Assert.IsTrue(result, "Expected result to be true"); 
} 

[Test] 
public void ShouldReturnFalseWhenPassedLowerCaseHappy() 
{ 
    var classUnderTest = new SomeClassTestAdapter(); 
    bool result = classUnderTest.IsHappy("happy"); 
    Assert.IsFalse(result, "Expected result to be false"); 
} 

[Test] 
public void ShouldReturnFalseWhenPassedNull() 
{ 
    var classUnderTest = new SomeClassTestAdapter(); 
    bool result = classUnderTest.IsHappy(null); 
    Assert.IsFalse(result, "Expected result to be false"); 
} 

스텁 또는 몰에 압착해야이 코드에 좋은 곳이 없다

하는 경우 이 경우 어댑터 클래스를 만들지 않으려면 Moles와 같이 크고 유급 인 의존성이 아닌 내장 된 .Net 기능을 사용할 수 있습니다. 반사 및 동적으로 보호 된 회원 또는 비공개 회원에게 액세스 할 수 있습니다. 이 예를 참조하십시오

+0

IsHappy 메서드가 'protected'입니다. Class-Under-Test에서 메서드를 직접 호출하여 액세스 할 수 없습니다. – Ian

+0

@ 이안 : 죄송 합니다만이 일로 돌아가려면 너무 오래 걸렸습니다. 내 대답 업데이트 –

2

내가 여기 스텁에 대해 잊지 것입니다. 스텁/모의는 종속성의 동작을 위장하려는 경우에 사용됩니다. 테스트 싶어 SomeClassClient이 있다면 당신은 당신의 SomeClass 스텁 것하고 SomeClass 사용 : FooClient을 테스트 할 때이 예에서는

public class Foo 
    { 
     public virtual int GetFoosInt() 
     { 
      return 12; 
     } 
    } 
    public class FooClient 
    { 
     private Foo _foo; 

     public FooClient(Foo foo) 
     { 
      _foo = foo; 
     } 

     public int AddOneToFoosInt() 
     { 
      return _foo.GetFoosInt() + 1; 
     } 
    } 

를, 무엇을 테스트 할 것은()이 GetFoosInt "보다 1 반환 것입니다 ". FoClient를 테스트하기 위해 FoosInt가 무엇인지는 실제로 상관하지 않습니다. 그래서, 당신이 원하는 것을 반환하도록 GetFoosInt를 설정할 수있는 Foo 스텁을 생성합니다. 귀하의 경우에는

, 보호 된 가상 멤버를 테스트, 나는이 갈 것입니다 : 이것은 당신에게 보호 된 가상 테스트하기 위해 기본 동작에 '직접'액세스 할 수

[TestClass] 
public class SomeClassTest 
{ 
    private class DummySomeClass : SomeClass 
    { 
     public bool IsHappyWrapper(string mood) 
     { 
      return IsHappy(mood); 
     } 
    } 

    [TestMethod] 
    public void SomeTest() 
    { 
     var myClass = new DummySomeClass(); 

     Assert.IsTrue(myClass.IsHappyWrapper("Happy")); 
    } 
} 

. 주의 할 점은 추상 멤버를 정의하고 일반적으로 SomeClass에 추가하기 시작하면이 가상 상속자에 추가하여 테스트 유지 관리 오버 헤드를 추가해야한다는 것입니다.

저의 순수 주의자는 보호 된 회원을 남겨두고 공개 인터페이스를 통해서만 테스트해야한다고 말합니다. 하지만, 귀하의 상황에서 실용적 일 수도 있고 아닐 수도 있습니다. 나는이 접근법에 아무런 해가되지 않습니다.

+0

Moles.NET에 "자동화"할 수있는 기능이 있습니까? Moul (Fallthrough 등)에는 몇 가지 행동 컨트롤이 있습니다.Dummy 클래스를 수동으로 생성하는 대신 사용할 수 있습니까? – Ian

+0

잘 모르겠습니다. 필자는 주로 제 3 자 정적 메소드, 파일, GUI 등과 같은 외부 종속성을 모의하기 위해 Moles를 사용했습니다. 대신 Moock을 대신 사용하는 일반 조롱 엔진으로 많이 사용하지 않았습니다. 두더지는 꽤 강력합니다. 그래서 가능하다면 저를 놀라게하지는 않을 것입니다.하지만 불행히도, 나는 어떻게 해야할지 모르겠습니다. –

+0

이전에 MSTest는 보호 된/개인 멤버를 노출시키는 특별 어셈블리 인 '접근 자'를 생성 할 수있었습니다. 불행히도, 그들은 그 기능에 대한 지원을 취소 한 것 같습니다 (비록 내가 그것을 읽은 것을 기억하지는 못한다). –