gpt4 book ai didi

c# - 如何注入(inject)与 Moq 一起使用的模拟程序集

转载 作者:行者123 更新时间:2023-11-30 12:42:56 25 4
gpt4 key购买 nike

我的 Controller 中有一个方法可以将当前正在执行的程序集中的属性数据返回到分部 View 中。

在这个例子中,我只是提取标题,但我需要用它做更多的事情。

Controller :

    var title = "";

var asm = Assembly.GetExecutingAssembly();
var attrs = asm.GetCustomAttributes(typeof(AssemblyTitleAttribute));
var titleAttr = (AssemblyTitleAttribute)attributes[0];

title = titleAttr.Title;

return PartialView("_Build", title);

在 Moq 中编写单元测试时,我需要找到一种方法将 Assembly 属性注入(inject)到 mock 中,以便在运行 Controller 测试时验证是否生成了正确的属性,然后执行 x 或 y用我的断言。

单元测试:

    //Arrange
//The magic I need to happen.

//Act
var controller = GetController();
var result = controller.MyMethod() as PartialViewResult;
var title = result.Model;

//Assert
Assert.AreEqual("Title", title); //currently static, need to verify against a mock

我知道这是一组极其简单的代码,但此时我只需要概念证明。

有没有好的方法来创建一个假的程序集?我需要使用 System.Reflection.Emit 吗?

最佳答案

您可以创建一个虚拟方法,例如GetCustomAttributes 提供给定类型的属性。然后在您的测试项目中,一个可测试类将从 Controller 类派生并覆盖此方法。

Home Controller:

private IDependency _someDependency;

public HomeController(IDependency someDependency)
{
_someDependency = someDependency;
}

public ActionResult MyMethod()
{
var title = "";
var version = "";

IEnumerable<Attribute> attributes = GetCustomAttributes(typeof(AssemblyVersionAttribute)).ToList();
AssemblyVersionAttribute verAttr = attributes.OfType<AssemblyVersionAttribute>().FirstOrDefault();
if (verAttr != null) version = verAttr.Version;

attributes = GetCustomAttributes(typeof(AssemblyTitleAttribute)).ToList();
AssemblyTitleAttribute titleAttr = attributes.OfType<AssemblyTitleAttribute>().FirstOrDefault();
if (titleAttr != null) title = titleAttr.Title;

return PartialView("_Build", title + version);
}

public virtual IEnumerable<Attribute> GetCustomAttributes(Type attributeType)
{
var asm = Assembly.GetExecutingAssembly();
var attrs = asm.GetCustomAttributes(attributeType);
return attrs;
}

Test:

[TestClass]
public class MyMethodTest
{
[TestMethod]
public void MyMethod_WhenCalled_PartialViewIsReturned()
{
// Arrange
// The magic I need to happen.

Mock<IDependency> dependencyStub = new Mock<IDependency>();
// dependencyStub.Setup(...).Returns(...);
var controller = new TestableHomeController(dependencyStub.Object)
{
UseFakeAttributes = true
};

// Act
var result = controller.MyMethod() as PartialViewResult;

// Assert
var model = result.Model;
Assert.AreEqual("MyFakeTitle1.0.0.0", model); // currently static, need to verify against a mock
}

private class TestableHomeController : HomeController
{
public bool UseFakeAttributes { get; set; }

public TestableHomeController(IDependency someDependency)
:base(someDependency)
{ }

public override IEnumerable<Attribute> GetCustomAttributes(Type attributeType)
{
return UseFakeAttributes
? new List<Attribute>
{
new AssemblyTitleAttribute("MyFakeTitle"),
new AssemblyVersionAttribute("1.0.0.0"),
new AssemblyDescriptionAttribute("Assembly fake description")
// next attributes ...
}.Where(a => a.GetType() == attributeType)
: base.GetCustomAttributes(attributeType);
}
}
}

关于c# - 如何注入(inject)与 Moq 一起使用的模拟程序集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32234257/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com