1

我无法摆脱这个问题。这很奇怪,当我尝试在调试模式下运行我的 NUnit 测试时,我得到了预期的结果,但是当我正常运行它时,结果是错误的。

我想要做的是检测绑定错误。这是一个示例

[TestFixture, RequiresSTA]
public class BindingTests
{
    [Test]
    public void T1_BindingErrorsExpected()
    {
        string error = null;
        using (var listener = new ObservableTraceListener())
        {
            listener.TraceCatched += s => error = s;

            TextBlock myText = new TextBlock();
            UserControl control = new UserControl();
            Binding myBinding = new Binding("BadBinding");
            myBinding.Source = control;
            myText.SetBinding(TextBlock.BackgroundProperty, myBinding);
        }
        Assert.IsNotNull(error);
    }
}

和 ObservableTraceListener

public sealed class ObservableTraceListener : DefaultTraceListener
{
    private readonly StringBuilder _Builder = new StringBuilder();
    public ObservableTraceListener()
    {
        PresentationTraceListener.Add(SourceLevels.Error, this);
    }

    public new void Dispose()
    {
        Flush();
        Close();
        PresentationTraceListener.Remove(this);
        base.Dispose();
    }   

    public override void Write(string message)
    {
        _Builder.Append(message);
    }

    public override void WriteLine(string message)
    {
        Write(message);

        if (TraceCatched != null)
            TraceCatched(_Builder.ToString());

        _Builder.Clear();
    }

    public event Action<string> TraceCatched;
}


public static class PresentationTraceListener
{
    public static void Add(SourceLevels level, TraceListener trace)
    {
        PresentationTraceSources.DataBindingSource.Listeners.Add(trace);
        PresentationTraceSources.DataBindingSource.Switch.Level = level;
        PresentationTraceSources.ResourceDictionarySource.Listeners.Add(trace);
        PresentationTraceSources.ResourceDictionarySource.Switch.Level = level;
    }

    public static void Remove(TraceListener trace)
    {
        PresentationTraceSources.DataBindingSource.Listeners.Remove(trace);
        PresentationTraceSources.ResourceDictionarySource.Listeners.Remove(trace);
    }
}

结果调试 - >失败(我期望的)

结果运行->成功(不是预期的)

4

2 回答 2

1

谢谢 MatthewMartin,但我在https://github.com/bblanchon/WpfBindingErrors找到了解决方案

问题是我的ObservableTraceListener

我需要添加一个静态构造函数调用PresentationTraceSources.Refresh()以使其正常工作。正如 MSDN 文档中所说,它Refreshes trace sources, by forcing the app.config file to be re-read. 因此,当我在“调试”模式下开始测试时,刚刚完成了一些初始化,这可能导致 app.config 文件被读取。

MSDN 文档-> PresentationTraceSources.Refresh() http://msdn.microsoft.com/en-us/library/system.diagnostics.presentationtracesources.refresh%28v=vs.100%29.aspx

这是我的最终ObservableTraceListener结果,与PresentationTraceListener问题中的相同

public sealed class ObservableTraceListener : TraceListener
{
    private readonly StringBuilder _Builder = new StringBuilder();


    static ObservableTraceListener()
    {
        PresentationTraceSources.Refresh();
    }

    public ObservableTraceListener()
    {
        PresentationTraceListener.Add(SourceLevels.Error, this);
    }

    public new void Dispose()
    {
        Flush();
        Close();
        PresentationTraceListener.Remove(this);
        base.Dispose();
    }   

    public override void Write(string message)
    {
        _Builder.Append(message);
    }

    public override void WriteLine(string message)
    {
        _Builder.Append(message);

        if (TraceCatched != null)
            TraceCatched(_Builder.ToString());

        _Builder.Clear();
    }

    public event Action<string> TraceCatched;
}
于 2014-11-26T18:45:26.660 回答
0

发布答案是因为评论太小而无法容纳我想说的话...

互联网上没有对 PresentationTraceListener 的引用——它如何处理 TraceListener 很重要,因为 AFAIK PresentationTraceListener 是调用 TraceListener 的 Write/WriteLine 方法(可能间接通过 TraceSource)

下面的代码在一个全新的项目中编译。如果我写(x),我得到空值,如果我写线(x),我得到一个值。通常,当您编写自定义 TraceListener 时,您会将所有重载重定向到单个方法,以便它们的行为都相同(Write 和 WriteLine 应该相同,除了 WriteLine 在调用者的消息上添加换行符。)

另一个观察结果是 System.Diagnostics 跟踪是一个古怪的日志库,其主要优点是它始终可用,即使在使用 3rd 方库存在一些障碍时也是如此。System.Diagnostics 跟踪确实希望您在 app.config 或 web.config 中注册 TraceSwitch、TraceListener 并使用它来启用和禁用跟踪。它还需要注册 TRACE 标志(与在项目属性中注册 DEBUG 标志的方式相同——默认情况下,TRACE 是为 DEBUG 和 RELEASE 定义的)

[TestFixture, RequiresSTA]
public class BindingTests
{
    [Test]
    public void T1_BindingErrorsExpected()
    {
        string error = null;
        using (var listener = new ObservableTraceListener())
        {
            listener.TraceCatched += s => error = s;

            //TextBlock myText = new TextBlock();
            //UserControl control = new UserControl();
            //Binding myBinding = new Binding("BadBinding");
            //myBinding.Source = control;
            //myText.SetBinding(TextBlock.BackgroundProperty, myBinding);
            PresentationTraceSources.DataBindingSource.TraceEvent(TraceEventType.Error,0, "Hello World!");    
        }
        Assert.IsNotNull(error);
        Console.WriteLine(error);

    }
}

public sealed class ObservableTraceListener : TraceListener
{
    private readonly StringBuilder _Builder = new StringBuilder();
    public ObservableTraceListener()
    {
        //PresentationTraceListener.Add(SourceLevels.Error, this);
    }
    protected override void Dispose(bool disposing)
    {
        Flush();
        Close();
        //PresentationTraceListener.Remove(this);
    }

    public override void Write(string message)
    {
        _Builder.Append(message);
    }

    public override void WriteLine(string message)
    {
        Write(message);

        if (TraceCatched != null)
            TraceCatched(_Builder.ToString());

        _Builder.Clear();
    }

    public event Action<string> TraceCatched;
}
于 2014-11-26T17:26:57.170 回答