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

在Umbraco7.5.10单元测试中配置Mock IMember对象时属性赋值失效

解决Umbraco IMember Mock属性无法设置的问题

嘿,你遇到的这个问题其实是Moq处理接口对象的常见坑——当你创建Mock<IMember>时,生成的是一个动态代理对象,直接给.Object的属性赋值根本不会被Moq跟踪,所以调试时这些属性全是null就不奇怪了。

针对Umbraco的IMember接口,我们得换一种方式来配置属性值,用Moq的Setup方法来指定属性的返回逻辑,同时还要单独处理Umbraco特有的SetValue扩展方法。

修正后的测试代码

using NUnit.Framework;
using Umbraco.Core.Models;
using Site.Logic.Controllers.SurfaceControllers;
using System;
using Moq;
using Umbraco.UnitTesting.Adapter.Support;
using System.Collections.Generic;

namespace Site.Tests
{
    [TestFixture]
    public class InactiveMemberCheckTest
    {
        private UmbracoSupport support = new UmbracoSupport();
        private Mock<IMember> inactiveMemberEmailed;

        [SetUp]
        public void Setup()
        {
            support.SetupUmbraco();
            this.inactiveMemberEmailed = new Mock<IMember>();

            // 配置IMember标准属性的返回值
            inactiveMemberEmailed.Setup(m => m.LastLoginDate).Returns(DateTime.Today.AddMonths(-12));
            inactiveMemberEmailed.Setup(m => m.Name).Returns("inactiveMemberNotEmailed");
            inactiveMemberEmailed.Setup(m => m.Email).Returns("email@example.co.uk");

            // Mock自定义属性的SetValue方法
            inactiveMemberEmailed.Setup(m => m.SetValue("contactId", 1));
            inactiveMemberEmailed.Setup(m => m.SetValue("inactiveCheckEmailed", true));

            // 如果控制器需要读取这些自定义属性,还要配置GetValue的返回值
            inactiveMemberEmailed.Setup(m => m.GetValue<int>("contactId")).Returns(1);
            inactiveMemberEmailed.Setup(m => m.GetValue<bool>("inactiveCheckEmailed")).Returns(true);
        }

        [Test]
        public void MembersCanBeChecked()
        {
            var controller = new InactiveMemberCheckController(support.UmbracoContext);
            var resultInactiveEmailed = controller.InactiveCheck(inactiveMemberEmailed.Object);
            Assert.AreEqual(resultInactiveEmailed, true);
        }
    }
}

关键细节说明

  • 接口属性的正确Mock方式:IMember是接口,Moq生成的代理对象默认对所有属性getter返回默认值(null、0等)。必须用Setup(x => x.Property).Returns(value)来明确指定属性的返回值,而不是直接给.Object赋值——后者完全不会生效。
  • 自定义属性的处理:Umbraco的SetValue是扩展方法,底层调用的是IMember自身的SetValue方法,所以我们需要直接Mock这个方法。如果你的控制器逻辑里会读取这些自定义属性(比如用GetValue),一定要额外配置Setup(m => m.GetValue<T>(propertyAlias)).Returns(value),否则读取时还是会拿到默认值。
  • 额外提醒:如果控制器还用到了IMember的其他方法或属性,记得逐一Mock对应的行为,确保测试逻辑和预期一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 09:02:51