2008-09-16 12 views
12

저는 RhinoMocks를 처음 사용하고 있으며 두포에서 일어나는 일 이외에 구문에 대한 이해를 얻으려고합니다.RhinoMocks : 속성 가져 오기 도구를 모방하는 올바른 방법

사용자 개체가 있는데이를 User라고하며 IsAdministrator라는 속성이 있습니다. IsAdministrator 값은 사용자의 보안 사용 권한을 확인하는 다른 클래스를 통해 평가되며 해당 사용 권한에 따라 true 또는 false를 반환합니다. 이 User 클래스를 조롱하고 IsAdministrator의 반환 값을 위조하여 일부 단위 테스트를 격리하려고합니다.

public void CreateSomethingIfUserHasAdminPermissions() 
{ 
    User user = _mocks.StrictMock<User>(); 
    SetupResult.For(user.IsAdministrator).Return(true); 

    // do something with my User object 
} 

을 지금, 나는이 코뿔소가 프로퍼티 게터에에 '가짜'전화를 가고, 그냥 나에게 true를 반환되는 것을 기대 해요 :

이것은 내가 지금까지 뭘하는지입니다. 이것은 틀린가? 현재 IsAdministrator 속성의 종속성 때문에 예외가 발생합니다.

누군가 내 목표를 달성하는 방법을 설명 할 수 있습니까?

답변

11

한 빠른 노트 나는이에 뛰어 드 전에. 일반적으로 취성 테스트를하기 때문에 "Strict"모의의 사용을 피하기를 원합니다. 엄격한 모의 (mock)는 명시 적으로 Rhino가 일어날 것이라고 말하지 않는 것이 있으면 예외를 던질 것입니다. 또한 모의 작성 전화를 걸 때 Rhino가하고있는 일을 오해 할 수도 있습니다. 정의한 System.Type에서 파생되었거나 구현 된 사용자 정의 Object로 생각하십시오. 당신이 자신을 한 경우 그 결과는 다음과 같습니다

public class FakeUserType: User 
{ 
    //overriding code here 
} 

을 IsAdministrator은 사용자 유형에 단지 공공 재산이 아마도 당신이 상속 유형을 무시할 수 없기 때문에.

귀하의 질문에 관한 한, 귀하가이를 처리 할 수있는 여러 가지 방법이 있습니다. 다음과 같이 언급 aaronjensen로 사용자 클래스에 가상 속성으로 IsAdministrator을 구현할 수 :

public class User 
{ 
    public virtual Boolean IsAdministrator { get; set; } 
} 

이것은 확인 방법입니다,하지만 당신은 당신의 사용자 클래스에서 상속 계획 경우에만 가능합니다. 또한이 클래스에서 다른 멤버를 가짜로 만들지 않으려는 경우 가상 일 수도 있습니다. 이는 원하는 동작이 아닐 수 있습니다.

이 작업을 수행하는 또 다른 방법은 인터페이스를 사용하는 것입니다. 만약 당신이 모의하고 싶은 User 클래스라면 인터페이스를 추출 할 것입니다.

public interface IUser 
{ 
    Boolean IsAdministrator { get; } 
} 

public class User : IUser 
{ 
    private UserSecurity _userSecurity = new UserSecurity(); 

    public Boolean IsAdministrator 
    { 
     get { return _userSecurity.HasAccess("AdminPermissions"); } 
    } 
} 

public void CreateSomethingIfUserHasAdminPermissions() 
{ 
    IUser user = _mocks.StrictMock<IUser>(); 
    SetupResult.For(user.IsAdministrator).Return(true); 

    // do something with my User object 
} 

당신은 당신이 원하는 경우 애호가 얻을 수 dependency injection and IOC를 사용하지만 기본 원리는 전반적으로 동일합니다 : 귀하의 위의 예는 다음과 같이 보일 것입니다. 일반적으로 클래스는 구체적인 구현이 아닌 인터페이스에 의존하기를 원합니다.

이 정보가 도움이되기를 바랍니다. 필자는 주요 프로젝트에서 오랫동안 RhinoMock을 사용 해왔다. TDD와 조롱에 대해 나에게 질문하는 것을 망설이지 말라.

+1

IUser 스텁을 사용하기 전에 마지막 예제에'_mocks.ReplayAll()'이 필요하다는 점에주의하십시오. –

1

IsAdministrator가 가상인지 확인하십시오. 또한

, 당신은 _mocks.ReplayAll를 호출해야합니다()

0

_mocks.ReplayAll()은 아무 작업도 수행하지 않습니다. 카운트하지 않는 SetupResult.For()를 사용하기 때문입니다. Expect.Call()을 사용하여 코드가 모든 것을 올바르게 수행하는지 확인하십시오.