문제

저는 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
} 

이제 Rhino가 속성 getter에 대한 호출을 '가짜'로 설정하고 나에게 true를 반환할 것으로 예상됩니다.이것이 잘못된 것입니까?현재 IsAdministrator 속성의 종속성으로 인해 예외가 발생합니다.

여기에서 내 목표를 달성할 수 있는 방법을 설명해 줄 수 있는 사람이 있나요?

도움이 되었습니까?

해결책

이 문제에 뛰어들기 전에 한 가지 간단한 참고 사항이 있습니다.일반적으로 "엄격한" 모의 테스트는 취약한 테스트를 만들기 때문에 사용하지 않는 것이 좋습니다.Rhino가 일어날 것이라고 명시적으로 알리지 않은 일이 발생하면 엄격한 모의 모델은 예외를 발생시킵니다.또한 모의를 만들기 위해 호출을 할 때 Rhino가 정확히 무엇을 하는지 오해하고 있는 것이 아닐까 생각합니다.정의한 System.Type에서 파생되었거나 이를 구현하는 사용자 지정 개체로 생각하세요.직접 해보면 다음과 같을 것입니다.

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

IsAdministrator는 아마도 User 유형의 공용 속성일 뿐이므로 상속 유형에서는 이를 재정의할 수 없습니다.

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

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

이는 괜찮은 접근 방식이지만 User 클래스에서 상속할 계획인 경우에만 가능합니다.또한 이 클래스의 다른 멤버를 가짜로 만들고 싶지 않다면 그들도 가상이어야 하는데 이는 아마도 원하는 동작이 아닐 것입니다.

이를 달성하는 또 다른 방법은 인터페이스를 사용하는 것입니다.그것이 정말로 당신이 모의하고 싶은 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
}

원하는 경우 다음을 사용하여 더 좋아질 수 있습니다. 의존성 주입과 IOC 그러나 기본 원칙은 전반적으로 동일합니다.일반적으로 클래스가 구체적인 구현보다는 인터페이스에 의존하기를 원합니다.

이게 도움이 되길 바란다.저는 오랫동안 주요 프로젝트에서 RhinoMocks를 사용해왔으므로 주저하지 말고 TDD와 모킹에 대해 질문해 주세요.

다른 팁

IsAdministrator가 가상인지 확인하세요.

또한 _mocks.ReplayAll()을 호출해야 합니다.

_mocks.ReplayAll()은 아무 작업도 수행하지 않습니다.그것은 계산되지 않는 SetupResult.For()를 사용하기 때문입니다.코드가 모든 작업을 올바르게 수행하는지 확인하려면 Expect.Call()을 사용하세요.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top