Moq 对方法的各种mock

在上一节上我们看到一个示例。在这边我们要学习如何对各种形式的方法进行Mock和验证。

    public interface ISettingService
    {
        StudentSetting GetStudentSetting(string name);

        void GetStudentSettingOut(out StudentSetting setting);

        void GetStudentSettingRef(ref StudentSetting setting);

        T Get<T>(string name);
    }

    public class StudentSetting
    {
        public int MaxAge { get; set; }
        public string Name { get; set; }
    }

// 带ref参数需要这个委托
delegate void refCallback(ref StudentSetting setting);

    [Fact]
    public void Test_Method_Examples()
    {
        var studentSetting = new StudentSetting()
        {
            MaxAge = 1
        };

        //普通方法
        var settingService = new Mock<ISettingService>();
        settingService.Setup(x => x.GetStudentSetting("aa")).Returns(studentSetting);
        settingService.Object.GetStudentSetting("aa").Should().Be(studentSetting);
        settingService.Verify(x => x.GetStudentSetting("aa"), Times.Once);

        //泛型方法
        settingService.Setup(x => x.Get<StudentSetting>("aa")).Returns(studentSetting);
        settingService.Object.Get<StudentSetting>("aa").Should().Be(studentSetting);
        settingService.Verify(x => x.Get<StudentSetting>("aa"), Times.AtLeastOnce);

        //带out参数
        StudentSetting outStudentSetting = new StudentSetting() { MaxAge = 2, Name = DateTime.Now.Ticks.ToString() };
        settingService.Setup(x => x.GetStudentSettingOut(out outStudentSetting));
        settingService.Object.GetStudentSettingOut(out StudentSetting temp);
        temp.Should().Be(outStudentSetting);
        settingService.Verify(it => it.GetStudentSettingOut(out outStudentSetting), Times.AtLeastOnce);

        //带ref参数, 需要创建的委托 refCallback
        settingService.Setup(x => x.GetStudentSettingRef(ref It.Ref<StudentSetting>.IsAny))
            .Callback(new refCallback((ref StudentSetting setting) => {
                setting.MaxAge = 4;
            }));
        StudentSetting temp2 = new StudentSetting() { MaxAge = 3, Name = "ref" };
        settingService.Object.GetStudentSettingRef(ref temp2);
        temp2.MaxAge.Should().Be(4);
        temp2.Name.Should().Be("ref");
        settingService.Verify(it => it.GetStudentSettingRef(ref It.Ref<StudentSetting>.IsAny), Times.Exactly(1));

        //跟据参数,动态返回需要的值
        settingService.Setup(x => x.GetStudentSetting(It.IsAny<string>()))
            .Returns<string>(name =>
            {
                return new StudentSetting() { Name = name };
            });
        settingService.Object.GetStudentSetting("bb").Name.Should().Be("bb");

        //每次调用返回不同的值
        settingService.SetupSequence(x => x.GetStudentSetting("cc"))
            .Returns(new StudentSetting() { MaxAge = 3 })
            .Returns(new StudentSetting() { MaxAge = 4 })
            //这中间也是可以插入 exception的
            .Returns(new StudentSetting() { MaxAge = 5 });
        settingService.Object.GetStudentSetting("cc").MaxAge.Should().Be(3);
        settingService.Object.GetStudentSetting("cc").MaxAge.Should().Be(4);
        settingService.Object.GetStudentSetting("cc").MaxAge.Should().Be(5);
        settingService.Verify(it => it.GetStudentSetting("cc"), Times.Exactly(3));

        //抛出异常
        settingService.Setup(x => x.GetStudentSetting("ex")).Throws(new ArgumentException("ex"));
        Assert.Throws<ArgumentException>(() => settingService.Object.GetStudentSetting("ex"));
        settingService.Verify(it => it.GetStudentSetting("ex"), Times.Once);

        //在被回调的时候做一些事情,可以把验证直接放在这边
        settingService.Setup(x => x.GetStudentSetting(It.IsAny<string>())).Callback<string>((name) =>
        {
            name.Should().Be("callback");
        });
        settingService.Object.GetStudentSetting("callback");
    }

在验证函数被调用的时候,我们可以看到有一个类Times,通过这个我们可以用来判定这个函数的调用次数。

匹配方法参数

我们也可以在Mock的时候对方法的参数进行匹配

[Fact]
public void Count_Should_Return_Suitable_Quantity()
{
    var studentSetting = new StudentSetting()
    {
        MaxAge = 1
    };

    var settingService = new Mock<ISettingService>();
    //通过使用 is 我们可能 写出自己想要的条件
    settingService.Setup(x => x.GetStudentSetting(It.Is<string>(x => x.Contains("aa")))).Returns(studentSetting);
    settingService.Object.GetStudentSetting("aa").Should().Be(studentSetting);
    settingService.Verify(x => x.GetStudentSetting("aa"), Times.Once);
}

对属性进行Mock

public interface ISettingService
{
    string Name { get; set; }

    Abc Abc { get; }
}

public class Abc
{ 
    // 类里如果不定义成virtual Moq没有办法重写它
    public virtual string Name2 { get; set; }
}

[Fact]
public void Test_Properties()
{
    var settingService = new Mock<ISettingService>();
    settingService.SetupGet(x => x.Name).Returns("abc");
    settingService.Object.Name.Should().Be("abc");

    settingService.SetupGet(x => x.Abc.Name2).Returns("abc2");
    settingService.Object.Abc.Name2.Should().Be("abc2");
}
下一篇:Mock 实现类
最近更新的
...