2010-04-26 2 views
0

내 프로젝트에서 복잡한 람다 식을받는 일부 개체를 조롱하려고하면이 문제가 발생합니다. 대부분 대표의이 유형을받을 프록시 개체와 : 나는 그러나, 객체의 그 유형을 조롱 acomplish하는 MOQ뿐만 아니라 RhinoMocks를 사용하려고 모두 실패했다복잡한 람다식이 매개 변수로 조롱 된 개체

Func<Tobj, Fun<TParam1, TParam2, TResult>> 

.

가 미안이 일을하려고 무엇의 예를 단순화 :

public class Calculator 
{ 
    public int Add(int x, int y) 
    { 
      var result = x + y; 
      return result; 
    } 

    public int Substract(int x, int y) 
    { 
      var result = x - y; 
      return result; 
    } 
} 

다음, 나는 계산기 클래스의 모든 메소드에 매개 변수의 유효성을 확인해야합니다 : 첫째, 나는 계산을 수행하는 계산기 개체가 그래서 Single Responsibility 원칙을 지키기 위해 나는 validator 클래스를 만든다. 내가 프록시 클래스를 사용하여 모든 철사, 그 중복 된 코드를 가진 방지 : 미안이 CalculatorProxy을 사용하여 수행하는 구성 요소를 테스트, 마지막으로

public class CalculatorProxy : CalculatorExample.ICalculatorProxy 
{ 
    private ILimitsValidator _validator; 

    public CalculatorProxy(Calculator _calc, ILimitsValidator _validator) 
    { 
     this.Calculator = _calc; 
     this._validator = _validator; 
    } 

    public int Operation(Func<Calculator, Func<int, int, int>> operation, 
         int x, 
         int y) 
    { 
     _validator.ValidateArgs(x, y); 

     var calcMethod = operation(this.Calculator); 

     var result = calcMethod(x, y); 

     _validator.ValidateResult(result); 

     return result; 
    } 

    public Calculator Calculator { get; private set; } 
} 

을, 그래서 나는 코뿔소 모의 객체를 사용하여 예를 들어, 조롱하려는 :

[TestMethod] 
public void ParserWorksWithCalcultaroProxy() 
{ 

    var calculatorProxyMock = MockRepository.GenerateMock<ICalculatorProxy>(); 

    calculatorProxyMock.Expect(x => x.Calculator).Return(_calculator); 

    calculatorProxyMock.Expect(x => x.Operation(c => c.Add, 2, 2)).Return(4); 

    var mathParser = new MathParser(calculatorProxyMock); 

    mathParser.ProcessExpression("2 + 2"); 

    calculatorProxyMock.VerifyAllExpectations(); 
} 

그러나 나는 그것을 작동시킬 수 없습니다! Moq는 NotSupportedException으로 실패하고, RhinoMocks simpy에서는 결코 기대를 만족시키지 못합니다.

+0

@iCe - 번호가 매겨진 목록이 코드 영역과 싸우고있어서 질문을 따르기가 어려워서 제거했습니다. 변경 사항이 마음에 들지 않으면 사과하십시오. 다시 돌려보세요! –

+0

감사합니다. Jeff, 코드 영역에서 이상한 enconding을 제거하려고했습니다. –

+0

MathParser를 만들기 전에 calculatorProxyMock.ReplayAll()이 누락되었다고 생각합니다.테스트를 실행하는 동안 mock 객체는 여전히 "레코드"모드에 있습니다 (레코드 모드에있는 경우 VerifyAllExpectations가 실패 할 것이라고 생각 했습니까?) 물론 AAA sytnax를 선호하는 또 다른 이유입니다. – PatrickSteele

답변

0

마침내 나는 내 마음을 바꿨다. 기본 사항으로 돌아갑니다.

내가 알아야 할 것은 Calculator.Add 메서드가 올바른 인수로 호출되는지 여부입니다. 따라서 프록시에 단위 테스트가 적용된다는 점을 감안할 때 Calculator 객체를 조롱하고 실제 프록시를 사용해야한다고 생각합니다. 테스트의 의미를 바꾸지 않고 이전 솔루션보다 명확합니다. MOQ를 사용

은 다음과 같습니다

[TestMethod] 
    public void ParserWorksWithCalcultaroProxy() 
    { 
     var calculatorMock = new Mock<CalculatorExample.ICalculator>(); 

     calculatorMock.Setup(x => x.Add(2, 2)).Returns(4).Verifiable(); 

     var validatorMock = new Mock<ILimitsValidator>(); 

     var calculatorProxy = new CalculatorProxy(calculatorMock.Object, validatorMock.Object); 

     var mathParser = new MathParser(calculatorProxy, new MathLexer(new MathValidator())); 
     mathParser.ProcessExpression("2 + 2"); 

     calculatorMock.Verify(); 
    } 

는 또한 미안 대신 Rhino.Mocks의 MOQ 구문을 선호하기 시작했다.

1

나는이 사용 MOQ 주위에있는 방법을 발견했다 :

[TestMethod] 
    public void ParserWorksWithCalcultaroProxy() 
    { 
     var calculatorProxyMock = new Mock<ICalculatorProxy>(); 
     Func<Calculator, Func<int, int, int>> addMock = c => c.Add; 

     calculatorProxyMock.Setup(x => x.BinaryOperation(It.Is<Func<Calculator, Func<int, int, int>>>(m => m(_calculator) == addMock(_calculator)), 2, 2)) 
            .Returns(4).Verifiable();   

     var mathParser = new MathParser(calculatorProxyMock.Object); 

     mathParser.ProcessExpression("2 + 2"); 

     calculatorProxyMock.Verify(); 
    } 

내가 계산기 개체의 계산기 프록시를 통해 호출되고 어떤 방법을 테스트 할 수 있습니다이 방법은 MathParser가이 작업 발현을 분석한다는 것을 확인 .

저는 이것을 내 실제 프로젝트에 전달할 수있을 것이라고 생각합니다.

또한, 나는 MOQ에, 람다 식의 매개 변수를 지원하는이 최종 4.0 릴리스를 대상으로, 개방 문제가 발견 : Moq Open Issues에만 작동합니까 그러나 람다 식의 매개 변수를 조롱에 대한 수정이 있습니다

간단한 람다 표현식으로. 너는 그것을 얻을 수있다 here

+0

나는 또한 이 경우 계산기 오브젝트만을 조롱하는 것이 더 좋다고 생각하기 시작하고 실제 프록시를 사용하십시오. 나는 문제가 없어야하므로 프록시로 테스트를 실시했다. 어쨌든 이것은 단위 테스트보다 더 기능적인 테스트이므로, 그런 식으로 진행하는 것이 좋습니다. –

관련 문제