title: gtest - ensure that a method is not called before, but can be called after a certain method call
body: <p>How can I test that <code>setState()</code> method is not called before <code>subscribe()</code>, while allowing but not forcing it to be called after?</p>
  
  <p>The code below shows what I want to achieve.</p>
  
  <p>This is the method I want to test:</p>
  
  <pre><code>...
  
  void FirstState::enter()
  {
      mInfoSubscription.subscribe(mInfoListener);
  
      mStateMachine.setState(mFactory.makeState(StateId::SecondState));
  }
  
  ...
  </code></pre>
  
  <p>This is a unit test:</p>
  
  <pre><code>class FirstStateTest : public ::testing::Test {
  protected:
      FirstStateTest()
          : mFirstState{mMockStateMachine, mMockStatesFactory,
                        mMockInfoSubscription, mMockInfoListener}
      {
      }
  
      NiceMock&lt;MockStateMachine&gt; mMockStateMachine;
      NiceMock&lt;MockStatesFactory&gt; mMockStatesFactory;
      NiceMock&lt;MockInfoSubscription&gt; mMockInfoSubscription;
      NiceMock&lt;MockInfoListener&gt; mMockInfoListener;
  
      FirstState mFirstState;
  };
  
  TEST_F(FirstStateTest, ensure_that_subscription_is_done_before_state_change)
  {
      // This method must not be called before "subscribe()".
      EXPECT_CALL(mMockStateMachine, doSetState(_)).Times(0);  // doesn't work the way I want
  
      EXPECT_CALL(mMockInfoSubscription, subscribe(_)).Times(1);
  
      // At this moment it doesn't matter if this method is called or not.
      EXPECT_CALL(mMockStateMachine, doSetState(_)).Times(AtLeast(0));  // doesn't work the way I want
  
      mFirstState.enter();
  }
  
  // other unit tests ...
  ...
  </code></pre>
  
  <p><strong>Edit 1:</strong> </p>
  
  <p>Just in case, this is how <code>MockStateMachine</code> looks:</p>
  
  <pre><code>class MockStateMachine : public IStateMachine {
  public:
      MOCK_METHOD1(doSetState, void(IState* newState));
      void setState(std::unique_ptr&lt;IState&gt; newState) { doSetState(newState.get()); }
  };
  </code></pre>