如何在nsubstitute mock上测试set方法

时间:2016-03-16 16:03:26

标签: unit-testing unity3d nunit nsubstitute

我正在完全重写这个,因为我正坐在我的项目前面。我仍然有理解如何正确编写测试的问题。

以下是我要测试的课程:

namespace Snowball.Controllers
{
    public class FollowCameraController : ICameraController
    {
        private ITransform player;
        private ITransform camera;
        private IVector3Utility utility;
        private IVector3 offset;

        public FollowCameraController(ITransform player, ITransform camera, IVector3Utility utility)
        {
            this.player = player;
            this.camera = camera;
            this.utility = utility;

            offset = utility.Subtract(camera.Position, player.Position);
        }

        public void UpdateCameraPosition()
        {
            IVector3 playerPosition = player.Position;

            IVector3 newCameraPosition = utility.Add(playerPosition, offset);

            camera.Position = newCameraPosition;
        }
    }
}

这是我正在运行的测试套件,它是我现在试图测试的套件中唯一的测试:

namespace FrameworkTests
{
    [TestFixture]
    public class FollowCameraControllerTest
    {
        private ITransform cameraTransformMock;
        private ITransform playerTransformMock;
        private IVector3Utility utilityMock;

        private IVector3 offset;

        private FollowCameraController sut;

        [SetUp]
        public void Init()
        {
            cameraTransformMock = Substitute.For<ITransform>();
            playerTransformMock = Substitute.For<ITransform>();
            utilityMock = Substitute.For<IVector3Utility>();

            offset = Substitute.For<IVector3>();

            utilityMock.Subtract(Arg.Any<IVector3>(), Arg.Any<IVector3>()).Returns(offset);

            sut = new FollowCameraController(cameraTransformMock, playerTransformMock, utilityMock);

            var temp = utilityMock.Received().Subtract(Arg.Any<IVector3>(), Arg.Any<IVector3>());
        }

        [Test]
        public void WhenUpdateCameraIsCalledThenCameraPositionIsUpdated()
        {
            //var playerPosition = Substitute.For<IVector3>();
            var cameraPosition = Substitute.For<IVector3>();

            var playerPosition = playerTransformMock.Position;

            utilityMock.Add(playerPosition, offset).Returns(cameraPosition);

            //var temp = cameraTransformMock.Position;
            //cameraTransformMock.Position = cameraPosition;

            sut.UpdateCameraPosition();

            var temp = playerTransformMock.Received().Position;
            temp = utilityMock.Received().Add(playerPosition, offset);
            //cameraTransformMock.Received().Position = cameraPosition;
        }
    }
}

此测试失败,出现以下失败的测试输出:

结果讯息: NSubstitute.Exceptions.ReceivedCallsException:预计会收到一个匹配的呼叫:

添加(IVector3Proxy,IVector3Proxy) 实际上没有收到匹配的电话。 收到1个不匹配的呼叫(不匹配的参数用&#39; *&#39;字符表示):     添加( IVector3Proxy ,IVector3Proxy)

我希望有人可以指出我做错了什么或者我如何滥用NSubstitute。我迷失了如何测试这种方法

1 个答案:

答案 0 :(得分:1)

FollowCameraController构造函数需要player然后camera

public FollowCameraController(ITransform player, ITransform camera, IVector3Utility utility) { ... }

但是您的测试使用sut然后camera实例化player

sut = new FollowCameraController(cameraTransformMock, playerTransformMock, utilityMock);

我认为这是问题的很大一部分。 :)

另外,UpdateCameraPosition使用玩家位置和IVector3Utility实例更新相机位置,所以我会将其作为测试的重点:

    [Test]
    public void WhenUpdateCameraIsCalledThenCameraPositionIsUpdated()
    {
        var newCameraPosition = Substitute.For<IVector3>();
        var playerPosition = playerTransformMock.Position;
        utilityMock.Add(playerPosition, offset).Returns(newCameraPosition);

        sut.UpdateCameraPosition();

        Assert.AreSame(cameraTransformMock.Position, newCameraPosition);
    }