2013-06-27 4 views
2

그래서 비즈니스 로직 레이어에 대한 테스트 케이스를 작성하려고합니다. 나는 이미 NHibernate IQueryOver 객체를 반환하는 데이터 액세스 레이어를 조롱했습니다. IQueryOver 인터페이스를 구현하는 MockQueryOver 클래스를 만들었습니다. 왜냐하면 비즈니스 로직 레이어에 기능을 연결하여 스텁 된 IQueryOver을 만드는 것이 나에게 적합하지 않았기 때문입니다.모의 Hibernate IQueryOverOrderBuilder 객체

어쨌든, 그 모든 작동하지만 문제는 내가 에 OrderBy() 할 때입니다.

public IQueryOverOrderBuilder<TRoot, TSubType> OrderBy(Expression<Func<TSubType, object>> path) 
{ 
    var func = path.Compile(); 
    IList<TSubType> result = m_data.OrderBy(func).ToList(); 
    var mockRepo = new MockRepository(); 
    var queryOver = new MockQueryOver<TRoot, TSubType>(m_data); 

    IQueryOverOrderBuilder<TRoot, TSubType> mockOrderBuilder = mockRepo.StrictMock<IQueryOverOrderBuilder<TRoot, TSubType>>(queryOver, path); 
    mockOrderBuilder.Stub(x => x.Desc).Return(queryOver); 
    mockOrderBuilder.Stub(x => x.Asc).Return(queryOver); 

    return mockOrderBuilder; 
} 

문제는 RhinoMocks가 스텁 방법 중 하나에 예외가 발생한다는 것입니다 : 내 MockQueryOver 클래스에서, 지금이 바로 같은 OrderBy() 방법을 구현한다. 이것은 예외 : 나는 자 NHibernate 및 RhinoMocks에 새로 온 사람

System.NullReferenceException : Object reference not set to an instance of an object. 
at NHibernate.Criterion.Lambda.QueryOverOrderBuilderBase`3.AddOrder(Func`2 orderStringDelegate, Func`2 orderDelegate) 
at NHibernate.Criterion.Lambda.QueryOverOrderBuilderBase`3.get_Desc() 
at NHibernate.Criterion.QueryOverBuilderExtensions.Desc(IQueryOverOrderBuilder`2 builder) 
at BLL.Tests.Mock_Objects.MockQueryOver`2.<OrderBy>b__7(IQueryOverOrderBuilder`2 x) in MockQueryOverSubType.cs: line 239 

, 그래서 나는이 장면 뒤에 무엇을하고 있는지 모르겠지만, 심지어는 인터페이스의 모형을 만드는거야하지만 것 같다, 메소드를 스텁하려고하면 여전히 구체적인 확장 메소드를 호출합니다.

이 문제를 명확히하거나 도와 주실 수 있습니까? 또한이 테스트 사례를 작성하기 시작한 이래로, 자유롭게 사용할 수있는 한 조롱 프레임 워크를 전환하는 데 신경 쓰지 않습니다.

고맙습니다.

답변

3

특정 IQueryOverOrderBuilder은 (는) 인터페이스입니까? a confusingly-named class that implements QueryOverOrderBuilderBase 인 것 같습니다. 이 상황에서 동작이 무엇인지 확실하지 않지만 이 IQueryOverOrderBuilder 인 것으로 생각됩니다. 실제로 설정되지 않은 해당 기본 클래스를 통해 호출 중이며보고있는 예외가 throw됩니다.

아마 당신은 당신이 비즈니스 로직과 NHibernate 사이에 또 ​​다른 추상화 레이어를 추가 할 필요가있을 것이라고 생각합니다. do not do IQueryOverOrderBuilder과 같은 구체적인 클래스를 조롱하는 방법이 RhinoMocks에 있다고 생각합니다. (하지만 수정이있어서 기쁩니다 :).

다른 추상화 계층을 생성하려면 현재 NHibernate와 상호 작용하는 비즈니스 로직의 연산을 분석하고, 이러한 연산을 캡슐화하는 새로운 인터페이스 인터페이스 (예 : IRepository)를 정의하십시오. NHibernate를 통해 데이터베이스에 무엇인가를 추가하는 코드는 AddItem이라는 인터페이스에서 함수가 될 수 있습니다. 이 인터페이스 뒤의 NHibernate와 상호 작용하는 코드를 새로운 클래스의 새로운 함수로 옮긴다. (하나의 클래스 일 필요는 없다. 논리적으로 관련된 코드를 별도의 인터페이스로 별도의 클래스로 그룹화 할 수있다.) 새 인터페이스는 쉽게 인스턴스화되거나 조롱 될 수있는 몇 가지 NHibernate 클래스와 인터페이스를 참조 할 수 있습니다 (이상적으로는 인터페이스가 NHibernate를 전혀 참조하지 않지만 테스트를 위해 인터페이스를 사용하고 코드를 완전히 분리하지 않는 것이 이상적입니다) NHibernate에서, 그래서 괜찮아요). 이 작업을 완료하면 비즈니스 로직을 새로운 인터페이스의 모의 객체 (또는 모의 객체)에 대해 단위 테스트 할 수 있으며, 해당 인터페이스를 구현하는 클래스는 실제 데이터베이스와의 통합 테스트가 가능합니다. 이것은 느슨하게 Adapter pattern입니다. 비즈니스 로직이 무엇을하는지 정확히 알지 못하면 디자인에 대해 더 논평하기가 어렵습니다. 이것이 도움이되기를 바랍니다. 당신이 MockRepository 당신의 자신을 만드는 경우

마지막으로, 나는 당신이 당신이 그들을 스텁 후에합니다 (MockRepository 또는 ReplayAll())가 만든 모의 객체에 Replay()를 호출 할 필요가 있다고 생각합니다.MockRepository의 정적 메서드에서 모의 ​​객체를 만드는 경우에는이 작업을 수행 할 필요가 없습니다. 귀하의 현재 문제와 관련이없는 것 같습니다 (비록 Stub 전화가 오면 전화를 걸어 차이가 있는지 확인해보십시오).하지만 어쨌든 언급하겠습니다.

+0

예, 인터페이스와 같은 구체적인 클래스라는 것이 맞습니다. 중간 계층을 만드는 방법에 대한 기본적인 예를 들어 주시겠습니까? 내가 뭘 할 수 있는지 잘 모르겠다. –

+0

비즈니스 논리와 NHibernate 사이에 추상화 계층을 만드는 방법에 대해 더 자세히 설명했습니다. 분명하고 도움이되기를 바랍니다. 그렇지 않은지 물어보십시오. –