You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用FakeItEasy验证公共方法调用?单元测试断言失败求解

问题:FakeItEasy单元测试断言失败,Play方法未触发Start调用

问题重现

单元测试中调用Fake生成的IPlayer实例的Play()方法后,断言Start(1)被调用失败,错误信息显示仅Play()被调用:

Message:
FakeItEasy.ExpectationException :

Assertion failed for the following call:
AsyncConsole.example1.IPlayer.Start(i: 1)
Expected to find it once or more but didn't find it among the calls:
1: IPlayer.Play()

相关代码

接口与实现类

public interface IPlayer
{
    public void Play();

    public void Start(int i);
}

public class Player : IPlayer
{
    public void Play()
    {
        Start(1);
    }

    public void Start(int i)
    {
        Console.WriteLine("Start " + i);
    }
}

原测试类

using FakeItEasy;
using Xunit;

namespace TestProject
{
    public class TestPlayer
    {
        [Fact]
        public void Play_WhenCalled_ShouldCallStart()
        {
            var player = A.Fake<IPlayer>();
            player.Play();

            //assert
            A.CallTo(() => player.Start(1)).MustHaveHappened();
        }
    }
}

原因分析

A.Fake<IPlayer>()生成的是完全模拟的Fake对象,FakeItEasy会为接口方法生成空实现。调用该Fake对象的Play()时,并不会执行Player类中Play()的真实逻辑(即调用Start(1)),仅会记录Play()的调用行为,因此断言Start(1)被调用必然失败。

解决方案

方案1:测试真实Player类的行为(推荐)

如果测试目标是验证Player类中Play()是否正确调用自身的Start(1),需创建Player的部分模拟(Partial Fake),让FakeItEasy执行Play()的真实逻辑,同时监控Start()的调用:

using FakeItEasy;
using Xunit;
using AsyncConsole.example1; // 引入Player所在命名空间

namespace TestProject
{
    public class TestPlayer
    {
        [Fact]
        public void Play_WhenCalled_ShouldCallStart()
        {
            // 创建Player的Partial Fake,配置调用基类真实方法
            var player = A.Fake<Player>(options => options.CallsBaseMethods());
            
            player.Play();

            // 断言Start(1)被调用至少一次
            A.CallTo(() => player.Start(1)).MustHaveHappened();
        }
    }
}

方案2:配置Fake对象的Play()方法触发Start()

如果测试目标是验证依赖IPlayer的其他组件行为,而非Player自身实现,可手动配置Fake对象的Play()方法调用Start(1):

using FakeItEasy;
using Xunit;

namespace TestProject
{
    public class TestPlayer
    {
        [Fact]
        public void Play_WhenCalled_ShouldCallStart()
        {
            var player = A.Fake<IPlayer>();
            
            // 配置调用Play()时自动执行Start(1)
            A.CallTo(() => player.Play()).Invokes(() => player.Start(1));
            
            player.Play();

            A.CallTo(() => player.Start(1)).MustHaveHappened();
        }
    }
}

内容的提问来源于stack exchange,提问作者Mike Bluer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 13:41:00