c# - 如何使用 NSubstitue 框架从 Controller 类模拟基方法

标签 c# unit-testing testing mocking nsubstitute

当 Controller 类中的 Action 方法调用它时,我需要模拟基类中存在的方法。

下面是我的 Controller 类,操作方法 Index() 调用基方法 GetNameNodeStatus()。现在,当操作方法 Index 使用 Nsubstitute 模拟框架调用它时,我如何模拟基类中存在的 GetNameNodeStatus()

using Cluster.Manager.Helper;
using Cluster.Manager.Messages;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Mvc;

namespace Cluster.Manager
{
    public class HomeController : Controller
    {
        // GET: Home
        public ActionResult Index()
        {
            ClusterMonitoring monitoring = new ClusterMonitoring();
            string getStatus = monitoring.GetNameNodeStatus("", new Credential());
            return View();
        }
     }
}

这是我的基类 Clustermonitoring

namespace Cluster.Manager.Helper
{
    public class ClusterMonitoring
    {
        public virtual string GetNameNodeStatus(string hostName, Credential credential)
        {
            return "Method Not Implemented";
        }
    }
}

这是我的测试课

namespace NSubstituteControllerSupport
{
    [TestFixture]
    public class UnitTest1
    {

        [Test]
        public void ValidateNameNodeStatus()
        {
            var validation = Substitute.ForPartsOf<ClusterMonitoring>();
            validation.When(actionMethod => actionMethod.GetNameNodeStatus(Arg.Any<string>(), Arg.Any<Credential>())).DoNotCallBase();
            validation.GetNameNodeStatus("ipaddress", new Credential()).Returns("active");
            var controllers = Substitute.For<HomeController>();
            controllers.Index();
        }
    }
}

最佳答案

ClusterMonitoring 是在方法中手动创建的。

ClusterMonitoring monitoring = new ClusterMonitoring();

这意味着替换它是不可能的。您需要将 ClusterMonitoring 作为 Controller 的依赖项注入(inject),以便能够在测试时替换它。

接口(interface)背后的第一个抽象ClusterMonitoring

public interface IClusterMonitoring  {
    string GetNameNodeStatus(string hostName, Credential credential);
}

让它继承那个接口(interface)

public class ClusterMonitoring : IClusterMonitoring {
    public virtual string GetNameNodeStatus(string hostName, Credential credential) { ... }
}

更新 Controller 以通过构造函数获取依赖

public class HomeController : Controller {
    private readonly IClusterMonitoring monitoring;

    public HomeController(IClusterMonitoring monitoring) {
        this.monitoring = monitoring;
    }

    // GET: Home
    public ActionResult Index() {
        var status = monitoring.GetNameNodeStatus("", new Credential());
        return View(status);
    }
 }

现在更新测试以将依赖项注入(inject)被测 Controller

[TestFixture]
public class UnitTest1 {

    [Test]
    public void ValidateNameNodeStatus() {
        //Arrange
        var expected = "active";
        var validation = Substitute.For<IClusterMonitoring>();
        validation.GetNameNodeStatus("", new Credential()).Returns(expected);
        var controller = new HomeController(validation);

        //Act
        var actual = controllers.Index() as ViewResult;

        //Assert
        Assert.IsNotNull(actual);
        Assert.AreEqual(expected, actual.Model); 
    }
}

关于c# - 如何使用 NSubstitue 框架从 Controller 类模拟基方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41849606/

相关文章:

c# - 如何按 2 列比较两个 csv 文件?

c# - 正则表达式:用特殊字符替换数字中间的位数

sql - 如何在go lang中测试事务回滚和提交

c# - 单元测试功能

ios - OCMock: stub 从不匹配签名

testing - iGoogle Gadget 私有(private)开发

testing - yql和开表开发如何搭建开发环境?如何在本地进行测试? (最佳实践)

c# - 正则表达式模式 number1 到 number2

winforms - 与 White 的集成测试

c# - HiQPdf 将文档合并为一个 pdf 然后应用分页