如何使用 NSubstitue 框架从 Controller class 模拟基本方法
How do I mock a base method from the Controller class using the NSubstitue framework
当控制器 class 中的 Action 方法调用它时,我需要一个模拟基 class 中存在的方法。
下面是我的控制器class,动作方法Index()
调用基方法GetNameNodeStatus()
。现在,当操作方法 Index
使用 Nsubstitute 模拟框架调用它时,我如何模拟基 class 中存在的 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();
}
}
}
这是我的基础class集群监控
namespace Cluster.Manager.Helper
{
public class ClusterMonitoring
{
public virtual string GetNameNodeStatus(string hostName, Credential credential)
{
return "Method Not Implemented";
}
}
}
这是我的测试class
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
作为控制器的依赖项注入,以便能够在测试时将其替换掉。
第一个抽象ClusterMonitoring
接口
public interface IClusterMonitoring {
string GetNameNodeStatus(string hostName, Credential credential);
}
并让它继承那个接口
public class ClusterMonitoring : IClusterMonitoring {
public virtual string GetNameNodeStatus(string hostName, Credential credential) { ... }
}
更新控制器以通过构造函数获取依赖项
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);
}
}
现在更新测试以将依赖项注入被测控制器
[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);
}
}
当控制器 class 中的 Action 方法调用它时,我需要一个模拟基 class 中存在的方法。
下面是我的控制器class,动作方法Index()
调用基方法GetNameNodeStatus()
。现在,当操作方法 Index
使用 Nsubstitute 模拟框架调用它时,我如何模拟基 class 中存在的 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();
}
}
}
这是我的基础class集群监控
namespace Cluster.Manager.Helper
{
public class ClusterMonitoring
{
public virtual string GetNameNodeStatus(string hostName, Credential credential)
{
return "Method Not Implemented";
}
}
}
这是我的测试class
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
作为控制器的依赖项注入,以便能够在测试时将其替换掉。
第一个抽象ClusterMonitoring
接口
public interface IClusterMonitoring {
string GetNameNodeStatus(string hostName, Credential credential);
}
并让它继承那个接口
public class ClusterMonitoring : IClusterMonitoring {
public virtual string GetNameNodeStatus(string hostName, Credential credential) { ... }
}
更新控制器以通过构造函数获取依赖项
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);
}
}
现在更新测试以将依赖项注入被测控制器
[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);
}
}