我能起订量添加属性模拟类? [英] Can I get Moq to add attributes to the mock class?

查看:188
本文介绍了我能起订量添加属性模拟类?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在写一个命令行界面到我的项目。用户输入创建项目富,并找到控制器负责项目,然后调用创建方法,将富作为第一个参数。

I'm writing a command-line interface to my project. The user enters "create project foo", and it finds the controller responsible for "project" and then invokes the Create method, passing "foo" as the first argument.

这在很大程度上依赖于属性和反思:控制器看起来是这样的:

It relies heavily on attributes and reflection: the controller looks something like this:

[ControllerFor("project")]
class ProjectController
{
    [ControllerAction("create")]
    public object Create(string projectName) { /* ... */ }
}

我想使用起订量在单元测试解析器,是这样的:

I'd like to use Moq in the unit tests for the parser, something like this:

Mock<IProjectsController> controller = new Mock<IProjectsController>();
controller.Expect(f => f.Create("foo"));

parser.Register(controller.Object);
parser.Execute("create project foo");

controller.VerifyAll();

添加属性的接口也不会出现工作 - 他们不是由派生类继承

Adding the attributes to the interface doesn't appear to work -- they're not inherited by derived classes.

我可以起订量添加属性的类被嘲笑?

Can I get Moq to add attributes to the class being mocked?

推荐答案

更新:我刚刚意识到你其实可以通过对现有类型添加属性<一个href=\"http://msdn.microsoft.com/en-us/library/system.componentmodel.typedescriptor.addattributes.aspx\">TypeDescriptor.AddAttributes,这可以针对一个实例或执行的一个类型:

Update: I've just realised that you can actually add attributes to an existing type by using TypeDescriptor.AddAttributes, which can be executed against an instance or a a type:

Mock<IRepository> repositoryMock = new Mock<IRepository>();

CustomAttribute attribute = new CustomAttribute();

// option #1: to the instance
TypeDescriptor.AddAttributes(repositoryMock.Object, attribute );

// option #2: to the generated type
TypeDescriptor.AddAttributes(repositoryMock.Object.GetType(), attributes);

如果你需要它,返回的​​addAttribute可以传递一个TypeDescriptorProvider到<一个href=\"http://msdn.microsoft.com/en-us/library/system.componentmodel.typedescriptor.removeprovider.aspx\">TypeDescriptor.RemoveProvider事后删除属性。

If you need it, AddAttribute returns a TypeDescriptorProvider that can be passed to TypeDescriptor.RemoveProvider to remove the attributes afterwards.

请注意,<一个href=\"http://msdn.microsoft.com/en-us/library/system.attribute.getcustomattributes%28v=vs.110%29.aspx\">Attribute.GetCustomAttributes不会发现以这种方式在运行时添加属性。相反,使用<一个href=\"http://msdn.microsoft.com/en-us/library/system.componentmodel.typedescriptor.getattributes.aspx\">TypeDescriptor.GetAttributes.

Be aware that Attribute.GetCustomAttributes will not find attributes added at runtime in this way. Instead, use TypeDescriptor.GetAttributes.

原来的答案

我不相信的起订量(或与此有关的任何其他嘲讽框架)支持自定义属性。我知道城堡代理(通常用于实际创建类的框架)的支持它,但会是没有办法通过起订量来访问它。

I don't belive Moq (or any other mocking framework for that matter) supports custom attributes. I do know that Castle Proxy (the framework commonly used to actually create the class) does support it, but there'd be no way to access it through Moq.

您最好的选择是抽象的加载方法,属性到一个界面(接受的类型和属性类型),然后嘲笑说。

Your best bet is to abstract your method of loading Attributes into an interface (that accepts the Type and the Attribute type) and then mock that.

编辑:例如:

public interface IAttributeStrategy
{
    Attribute[] GetAttributes(Type owner, Type attributeType, bool inherit);
    Attribute[] GetAttributes(Type owner, bool inherit);
}

public class DefaultAttributeStrategy : IAttributeStrategy
{
    public Attribute[] GetAttributes(Type owner, Type attributeType, bool inherit)
    {
        return owner.GetCustomAttributes(attributeType, inherit);
    }

    public Attribute[] GetAttributes(Type owner, bool inherit)
    {
        return owner.GetCustomAttributes(inherit);
    }
}

这是需要的属性类使用IAttributeStrategy的一个实例(无论是通过IoC容器,或在其选择性传递到构造函数)。通常这将是一个DefaultAttributeStrategy,但你现在可以以改写输出嘲笑IAttributeStrategy。

The class that needs the attributes uses an instance of IAttributeStrategy (either through an IoC container, or having it optionally passed into the constructor). Usually it will be a DefaultAttributeStrategy, but you can now mock IAttributeStrategy in order to override the output.

这听起来令人费解,但增加了一个抽象层是不是试图想真正模拟属性变得更加容易。

It might sound convoluted, but adding a layer of abstraction is much easier than attempting to trying to actually mock Attributes.

这篇关于我能起订量添加属性模拟类?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆