微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

c# – 如何注入模拟程序集以与Moq一起使用

我的控制器中有一个方法,它将当前正在执行的程序集中的属性数据返回到局部视图中.

在这个例子中,我只是拉动标题,但我需要做更多的事情.

控制器:

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属性注入到mock中,以便在运行控制器测试时验证是否生成了正确的属性,然后使用我的断言执行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,它提供给定类型的属性.然后在你的测试中,一个可测试的类将从控制器类派生并覆盖这个方法.

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);
        }
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐