2014-10-02 7 views
4

저는 대부분 GoogleMock에서 주문한 기대를 사용하고 있습니다. 따라서 EXPECT_CALL은 모두 testing::InSequence 개체의 범위 내에 작성되었습니다.Google Mock : 전체 주문보다 기대의 부분적인 주문이 더 까다로운 이유는 무엇입니까?

이제 나는 순서를 풀어서 기대를 2 개의 순서로 나눕니다. 테스트가 통과해야한다고 말 하겠지만, 실패했습니다. 충족되지 않은 전제 조건에 대해 불만을 토로합니다. 이것에 대해 어떻게 생각해야합니까?

편집 : 내 코드의 감소 버전 다음 INSEQUENCE가 for 루프 안에 중첩되어있는 경우

//InSequence s;          // uncomment this and it works 
for (int i = 1; i <= 2; ++i) 
{ 
    { 
     //InSequence s;        // uncomment this and it doesn't work 

     EXPECT_CALL(mock1, produceMessage(_)) 
      .WillOnce(DoAll(SetArgReferee<0>(val1), Return(false))) 
      .WillOnce(DoAll(SetArgReferee<0>(val2), Return(false))) 
      .WillOnce(DoAll(SetArgReferee<0>(val2), Return(false))); 

     EXPECT_CALL(mock2, handleEvent(A<MyType>())); 
     EXPECT_CALL(mock2, handleMessage(NotNull())); 
    } 
} 

그래서, 난 때 INSEQUENCE 경우에 비해, 편안한 요구하는 부분 순서를 가져야한다 바깥에있다.

오류가 나는군요 :

Mock function called more times than expected - returning default value. 
    Function call: handleMessage(0xd7e708) 
      Returns: false 
     Expected: to be called once 
      Actual: called twice - over-saturated and active 

와 다음, 테스트의 끝에서 다음 GoogleMock 학습 곡선에 좀 더 진행 한 후

Actual function call count doesn't match EXPECT_CALL(mock2, handleMessage(NotNull()))... 
     Expected: to be called once 
      Actual: never called - unsatisfied and active 
+0

몇 가지 예제 코드를 작성할 수 있습니까? –

+0

이 코드를 추가했습니다. – haelix

+1

추가 설명 : 3 번째 기대에'.RetiresOnSaturation()'을 추가하면 부분 주문 케이스가 수정됩니다. 하지만 내 실제 사례는 더 복잡합니다. – haelix

답변

4

, 나는 것이다 대답하려고 내 자신의 질문에 도움이 될 수있는 일반적인 방법입니다.

는 이제 완전히 주문 기대의 다음 예를 살펴 보자 :

이제
{ 
    InSequence s; 

    EXPECT_CALL(mock1, methodA(_));  // expectation #1 
    EXPECT_CALL(mock2, methodX(_));  // expectation #2 

    EXPECT_CALL(mock1, methodA(_));  // expectation #3 
    EXPECT_CALL(mock2, methodY(_));  // expectation #4 
} 

,의 두 가지의 순서를 슬라이스 할 수 있습니다.

{ 
    InSequence s; 

    EXPECT_CALL(mock1, methodA(_));  // expectation #1 
    EXPECT_CALL(mock2, methodX(_));  // expectation #2 
} 

{ 
    InSequence s; 

    EXPECT_CALL(mock1, methodA(_));  // expectation #3 
    EXPECT_CALL(mock2, methodY(_));  // expectation #4 
} 

목적은 두 서열로부터 기대 즉, # 2, # 3 # 4하지만 이하위한 전제로서 기대 # 1을 갖는 "병합"할 수 있도록하는 것이다.

mock1.methodA(); // call #1 
mock2.methodX(); // call #2 
mock1.methodA(); // call #3 
mock2.methodY(); // call #4 

이유 :

그러나, 다음의 일련의 호출은 완전히 주문의 기대가 아니라 "부분적으로 주문"사람을 만족 예제 단지 만족이 다음 완전히 주문 기대가 만족하는 이유는 명백하다 그들이 쓰여진 순서대로. InSequence 일 때 그들은 만족하자마자 퇴직합니다.

그러나 호출 # 1이 기대 # 3을 만족시키고 호출 # 2가 기대 # 2와 일치하기 때문에 "부분 순서화"시나리오가 작동하지 않습니다. 예상 # 2는 예상 # 1과 일치하므로 충족 될 수 없습니다. 전제 조건. 비록 기술적으로, 기대 # 1과 # 3은 동일하며, 동일한 순서에 속하지 않으므로 쓰기의 역순으로 충족되므로 실패합니다.

나는이 현상이 Google Mock에서 충분히 설명하지 못한다고 생각합니다. 나는 여전히 더 나은 공식화를 찾고있다. 나는 여기에 사용 된 "부분적인 주문"개념에 문제가 있다고 생각한다.

+0

이 문제에 대한 해결책을 찾았습니까? – idij

+0

no. 일반적인 것이 아닙니다. 나는 일반적인 해결책이 어떤 형태의 역 추적을 필요로한다고 믿는다. 그러나 나는 그것에 더 많은 생각을하지 않았다.덕분에 – haelix

+0

. 이 문제의 해결 방법은 하나의 블록에서 methodA를 매개 변수 중 하나의 값으로 차별화 할 수 있기 때문에 해결할 수있었습니다. 그런 다음 첫 번째 블록의 methodA를 그냥 일치시키고 두 번째 일치하는 모든 값은 match합니다. 분명히 그것은 어디서나 적용될 수는 없을 것입니다. 단지 제 문제에 꼭 맞았습니다. – idij