Azazel
Azazel

Reputation: 13

Expected invocation on the mock once, but was 0 times: With Moq

I am getting an error

Moq.MockException : 
Expected invocation on the mock once, but was 0 times: m => m.Position = Vector

Performed invocations:

   Mock<IMove:1> (m):

      IMove.Position
      IMove.Velocity
      IMove.Position = Vector

and below is the my code structure

using Moq;

namespace Lab1.Test
{
    public class UnitTest1
    {
        [Fact]
        public void Move_from_12_5_to_5_8_with_velocity_N7_3()
        {
            var move = new Mock<IMove>();

            move.SetupGet(m => m.Position).Returns(new Vector( 12, 5)).Verifiable();
            move.SetupGet(m => m.Velocity).Returns(new Vector( -5, 3)).Verifiable();

            ICommand moveCommand = new CMove(move.Object);

            moveCommand.Execute();

            move.VerifySet(m => m.Position = new Vector( 5, 8), Times.Once);
            move.VerifyAll();
        }
    }
}

and tested classes

 public class Vector
 {
   private int[] coordinates;
   private int coord_cont;
   public Vector(params int[] coordinates)
   {
     this.coordinates = coordinates;
     this.coord_cont = coordinates.Length;
   }
   public static Vector operator +(Vector a, Vector b)
   {
     Vector c = new(new int[a.coord_cont]);
     c.coordinates = (a.coordinates.Select((x, index) => x + b.coordinates[index]).ToArray());
     return c;
   }

   public override bool Equals(object? obj)
   {
     if (obj == null || obj is not Vector)
       return false;
     else
       return coordinates.SequenceEqual(((Vector)obj).coordinates);
   }

   public override int GetHashCode()
   {
     return coordinates.GetHashCode();
   }
 }

public interface IMove
{
  public Vector Position { get; set; }
  public Vector Velocity { get; }
}


public class CMove : ICommand
{
    private readonly IMove move;
    public CMove(IMove move)
    {
        this.move = move;
    }
    public void Execute()
    {
      move.Position += move.Velocity;
    }
}

I want to use Moq as a layout for interface tests. But when i try use VerifySet, i get an error. i try make a simple example of the using moq. i don't understand why invocation on the mock was 0 times/

I tried to find a solution on the internet, but I didn’t find any similar case

Upvotes: 1

Views: 81

Answers (1)

HellAbyss
HellAbyss

Reputation: 38

Please, change row

move.VerifySet(m => m.Position = new Vector( 5, 8), Times.Once);

to

move.VerifySet(m => m.Position = new Vector(7,8), Times.Once);

Because 12 - 5 is indeed 7, not 5 :)

I would recommend you to use constants in test to omit possibility of same mistakes in future. For example you could write your test like that:

using Moq;
using Xunit;

namespace Lab1.Test
{
    public class CMoveTests
    {
        [Fact]
        public void Move_Works_Correctly()
        {
            //Arrange
            var move = new Mock<IMove>();

            var vec1 = new Vector(12, 5);
            var vec2 = new Vector(-5, -3);

            move.SetupGet(m => m.Position).Returns(vec1).Verifiable();
            move.SetupGet(m => m.Velocity).Returns(vec2).Verifiable();

            ICommand moveCommand = new CMove(move.Object);
            
            //Act
            moveCommand.Execute();

            //Assert
            move.VerifySet(m => m.Position = vec1 + vec2, Times.Once);
            move.VerifyAll();
        }
    }
}

Upvotes: 1

Related Questions