Modifying or configuring output with StoryQ

依然范特西╮ 提交于 2019-12-11 13:15:38

问题


I posted this question on the StoryQ discussion boards, but by looking at the (lack of) responses to other questions, activity there seems sparse at best. I thought I'd let everyone here have a go.

Is there a way to modify or configure the output (both output window and file) to include custom strings? For example, one of my stories requires that a specific exception is thrown. To do this, I catch the exception and save it, then in a separate method test that it's non-null and of the required type. I'd like to be able to append the type of the exception to the output (much like parameters are appended to method calls).

For example

.Then(ExceptionIsThrown<ArgumentNullException>)

would result in the following output

then exception is thrown (ArgumentNullException)

回答1:


Thanks to Giorgio Minardi for guiding me to look into the StoryQ.Formatting namespace. There I discovered that I can override the method formatting using a simple attribute.

The API provides an OverrideMethodFormatAttribute (subclassed from the abstract class MethodFormatAttribute), which works if you want to use a specific string constant, but C# doesn't like the method's type parameters in attributes. This doesn't compile due to the T in the attribute:

[OverrideMethodFormat(string.Format("exception is thrown ({0})", typeof(T).Name))]
private void ExceptionIsThrown<T>() where T : Exception
{
    ...
}

The solution is to create another MethodFormatAttribute subclass that specifically searches the method for generic types and output them. This subclass is below:

public class GenericMethodFormatAttribute : MethodFormatAttribute
{
    private readonly string _textFormat;

    public GenericMethodFormatAttribute()
    {
        _textFormat = null;
    }

    public GenericMethodFormatAttribute(string textFormat)
    {
        _textFormat = textFormat;
    }

    public override string Format(MethodInfo method,
                                  IEnumerable<string> parameters)
    {
        var generics = method.GetGenericArguments();
        if (_textFormat == null)
        {
            var genericsList = string.Join<Type>(", ", generics);
            return string.Format("{0} ({1})",
                                 UnCamel(method.Name),
                                 genericsList);
        }
        return string.Format(_textFormat, generics);
    }
}

Usage is almost like the supplied attribute, except that you optionally supply a format string instead of a string constant. Omitting the format string un-camel-cases the method name just like the default behavior.

[GenericMethodFormatAttribute]
private void ExceptionIsThrown<T>() where T : Exception
{
    ...
}

This allows me to declare the attribute in my source, while not having to touch the StoryQ code. Ten points to StoryQ for extensibility!




回答2:


Best thing is to look at the sources of StoryQ, in particular look at the StoryQ.Formatting namespace. To get a particular output you should follow the FluenInterface pattern used within the framework and wrote your own method, something like ThenExceptionIsThrown(Exception ex) and chain it like the other methods in the story.



来源:https://stackoverflow.com/questions/15226666/modifying-or-configuring-output-with-storyq

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!