views:

120

answers:

2

This is my problem test:

    [Test]
    public void PlayerHasPointsIncreasedOnEnterByFifteen() {
        // Arrange.
        var playerOneFake = new Mock<IEntity>();
        playerOneFake.SetupGet(p => p.Score).Returns(0);
        var pointState = new PointState(playerOneFake.Object);
        // Act.
        pointState.Enter();
        // Assert
        IEntity entity = playerOneFake.Object;
        Assert.AreEqual(15, entity.Score, "Player score is incorrect");
    }

p.Score needs only to return zero once - the first time I check it in PointState. After this I need a non-mocked version to check the actually score has been incremented in the assert.

I know you can verify by a set amount of times - e.g. Times.Once() but how do I have this functionality in a set up?

Any ideas? It's driving me mad.

Cheers.

+1  A: 

Instead of configuring the property with Returns, configure it with Callback, and use a code that the first time returns 0 and from the second time invokes your real object. I have never used a callback with SetupGet, but it should be something like this (code not tested, it is just to illustrate the idea):

bool alreadyObtainedValue=false;

playerOneFake.SetupGet(p => p.Score).Callback(() => {
  if(alreadyObtainedValue) {
    return realObject.Score;
  } else {
    alreadyObtainedValue=true;
    return 0;
  }
});
Konamiman
+4  A: 

You seem to be testing the return value of a property on a Mock object, which doesn't really prove anything. Instead, you should be testing that the PointState object makes the expected call into IEntity (perhaps sets the Score property?) when you call the Enter method of the PointState object.

Assuming it sets a Score property, you would do something like

entity.VerifySet(x => x.Score = 15);
Mark Heath
That's it. I didn't think to check it in this manner and had my heart set on using an assert.Thanks.
Finglas