Search code examples
c#unit-testingxunitfluent-assertions

Mocking inner objects gets lost with function call


I am mocking chessboard, on which I can add pieces. I want to unit test allowed LinearMoves, when there are some pieces on the chessboard.

Code starts with:

Chessboard.Object.AddPiece(Piece_C1.Object);
Chessboard.Object.AddPiece(Piece_A3.Object);
Chessboard.Setup(x => x.GetPiece(C1.Object)).Returns(Piece_C1.Object);
Chessboard.Setup(x => x.GetPiece(A3.Object)).Returns(Piece_A3.Object);

As you can see I first setup chessboard and both pieces on this chessboard. I also mock GetPiece(IPosition) function, which should return IPiece.

If I try with debugger GetPiece(IPosition pos) function at the end of code above, everything is OK, piece is returned:

enter image description here

Now I create new object LinearMoves, where I pass chessboard as parameter:

linearMoves = new LinearMoves(Chessboard.Object, Piece_A1.Object);

When GetPiece with same position gets called in this new object, it returs null:

IPiece currentPiece = chessboard.GetPiece(currentPosition);

Basically like Piece_C1 and Piece_A3 were never added. Where are they lost? It seems like Chessboard created and Chessboard passed as parameter into constructor are not the same objects.

EDIT:

I've found out that this search with mocked object Mock returns correct result, search with IPosition doesn't return anything.

  1. Search with Mock<IPosition> returns correct result:

enter image description here

  1. Search with IPosition (but coordinates are the same) doesn't return anything:

enter image description here


Solution

  • The problem is that Position is a reference type,so two objects are equal only if they point to the same object.

    You need to help your setup method compare Positions

    chessboard.Setup(x => x.GetPiece(It.Is< Position>(k => k.X== "A" && K.Y ==3))).Returns(...);