【问题标题】:Moq and attributes起订量和属性
【发布时间】:2015-11-10 06:56:51
【问题描述】:

我正在尝试创建一个需要在模拟对象上设置属性的测试用例。我一直在关注this question 中的答案,但CommandEventProcessingDecorator 方法中的属性为空。

[Fact]
public void RaiseEvent_AfterCommandIsExecuted_WhenCommandIsAttributedWithRaiseEventEnabled()
{
    var command = new FakeCommand();
    Assert.IsAssignableFrom<ICommand>(command);

    var eventProcessor = new Mock<IProcessEvents>(MockBehavior.Strict);
    eventProcessor.Setup(x => x.Raise(command));

    var attribute = new RaiseEventAttribute
    {
        Enabled = true
    };

    var decorated = new Mock<IHandleCommand<FakeCommand>>(MockBehavior.Strict);
    TypeDescriptor.AddAttributes(decorated.Object, attribute); // Add the attribute
    decorated.Setup(x => x.Handle(command));

    var decorator = new CommandEventProcessingDecorator<FakeCommand>(eventProcessor.Object, () => decorated.Object);
    decorator.Handle(command);

    decorated.Verify(x => x.Handle(command), Times.Once);
    eventProcessor.Verify(x => x.Raise(command), Times.Once);
}

internal sealed class CommandEventProcessingDecorator<TCommand> : IHandleCommand<TCommand> where TCommand : ICommand
{
    private readonly IProcessEvents _events;
    private readonly Func<IHandleCommand<TCommand>> _handlerFactory;

    public CommandEventProcessingDecorator(IProcessEvents events, Func<IHandleCommand<TCommand>> handlerFactory)
    {
        _events = events;
        _handlerFactory = handlerFactory;
    }

    public void Handle(TCommand command)
    {
        var handler = _handlerFactory();
        handler.Handle(command);

        var attribute = handler.GetType().GetCustomAttribute<RaiseEventAttribute>(); // attribute
        if (attribute != null && attribute.Enabled)
        {
            _events.Raise(command);
        }
    }
}

我做错了什么?

【问题讨论】:

  • 来自原始答案:Be aware that Attribute.GetCustomAttributes will not find attributes added at runtime in this way. Instead, use TypeDescriptor.GetAttributes.

标签: c# moq custom-attributes xunit


【解决方案1】:

这实际上是在question referenced 中回答的。

正如老狐狸在对该问题的评论中指出的那样: 请注意,Attribute.GetCustomAttributes 不会找到在运行时以这种方式添加的属性。相反,请使用TypeDescriptor.GetAttributes.

我创建了一个获取属性的扩展方法:

/// <summary>
/// Gets a runtime added attribute to a type.
/// </summary>
/// <typeparam name="TAttribute">The attribute</typeparam>
/// <param name="type">The type.</param>
/// <returns>The first attribute or null if none is found.</returns>
public static TAttribute GetRuntimeAddedAttribute<TAttribute>(this Type type) where TAttribute : Attribute
{
    if (type == null) throw new ArgumentNullException(nameof(type));

    var attributes = TypeDescriptor.GetAttributes(type).OfType<TAttribute>();
    var enumerable = attributes as TAttribute[] ?? attributes.ToArray();
    return enumerable.Any() ? enumerable.First() : null;
}

用法:myClass.getType().GetRuntimeAddedAttribute&lt;CustomAttribute&gt;();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-08-29
    • 2010-09-25
    • 2013-05-24
    • 2023-04-02
    • 2011-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多