【问题标题】:log4net - LogicalThreadContext - and unit test caseslog4net - LogicalThreadContext - 和单元测试用例
【发布时间】:2014-05-14 17:32:54
【问题描述】:

我开始编写单元测试(MS Test,Resharper 作为测试运行器)。当我设置 LogicalThreadContext(见下文)时,我的测试用例会“中止”。有人知道为什么吗?这与单元测试在不同的线程上有关吗?我该如何解决这个问题?

[TestClass]
public class ContextInfoTest
{
    private ILog _log;


    [TestInitialize]
    public void TestInitialize()
    {
        // logging configured in assembly.info
        _log = LogManager.GetLogger(this.GetType()); 
    }


    [TestMethod]
    public void FigureOutWhyAborting()
    {
        string input = "blah";
        LogicalThreadContext.Properties["mypropertyname"] = input;

        string output = LogicalThreadContext.Properties["mypropertyname"] as string;
        Assert.AreEqual(input, output);
    }


    [TestMethod]
    public void ThisWorks()
    {
        string input = "blah";
        CallContext.LogicalSetData("mypropertyname", input);

        string output = CallContext.LogicalGetData("mypropertyname") as string;
        Assert.AreEqual(input, output);
    }

奇怪的是,如果我要调试并单步执行代码,Assert.AreEqual 确实会被调用并通过,所以在那行代码之后发生了一些事情......这就是为什么我认为它可能有一些东西与测试线程等有关。

谢谢!

更新: 所以我在 MSTest 中运行了这个测试,得到了这个异常(Resharper 没有显示)

单元测试适配器抛出异常: 成员 'log4net.Util.PropertiesDictionary,log4net, Version=1.2.13.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a' 的类型未解析..

我在 VS2013、.Net 4.5 上使用 log4net v1.2.13。

此链接似乎表明这是一个引用程序集问题,但没有解决方案。非常欢迎任何其他想法,GAC'ing log4net 不是一个选项。 https://issues.apache.org/jira/browse/LOG4NET-398

【问题讨论】:

  • 对我来说很好(运行和调试测试),但我没有使用 reSharper。也许尝试直接从 VS 而不是通过 ReShaper 运行它们

标签: multithreading unit-testing log4net


【解决方案1】:

我最终这样做是为了让它工作:

把它放在 TestCleanup() 方法中:

CallContext.FreeNamedDataSlot("log4net.Util.LogicalThreadContextProperties");

【讨论】:

  • 这在某种程度上可行,但并非总是如此。出于某种我不知道的原因,一些测试仍然会引发错误。
  • 在我的代码深处,我发现我们使用 log4net LogicalThreadContext 来设置一个属性,显然这一行导致了问题。释放命名数据槽对我有用,尽管我正在调查我们是否可以完全删除该行。如果我们在测试中遇到这些问题,我想知道它是否会在生产中产生副作用。
  • @Erik And Raymond:这对我不起作用。我正在使用 log4net.LogicalThreadContext.Properties[param.Key] = param.Value;但这一直因您原始帖子中的错误而失败。我现在尝试了 log4net.GlobalContext.Properties[param.Key] = param.Value;它似乎正在工作。有什么想法吗?
【解决方案2】:

所以,我非常感谢您解决这个问题并致电 FreeNamedDataSlot。这让我开始接受对我有用的答案。而不是传入类的完整命名空间,我只需要使用类名:

这是在我的数据访问层深处使用的:

MySession session  = (MySession)System.Runtime.Remoting.Messaging.CallContext.LogicalGetData("MySession");

[TestCleanup]
public void Cleanup()
{
    CallContext.FreeNamedDataSlot("MySession");
}

这对我来说很完美!希望这有助于其他人在使用 Visual Studio 的测试环境时。

【讨论】:

    【解决方案3】:

    我知道这有点旧,但以下对我有用。

    虽然我的项目和单元测试都引用了log4net,但在单元测试中没有配置。将我的 ThreadContext 助手更新为以下内容使我的测试成功。如果在您的单元测试中配置了 log4net,但您仍然遇到此问题,您可以关闭编译符号。

    var is_configured = log4net.LogManager.GetRepository().Configured;
    var props = is_configured
                ? (ContextPropertiesBase)LogicalThreadContext.Properties
                : (ContextPropertiesBase)ThreadContext.Properties;
    props[key] = value;
    

    【讨论】:

      【解决方案4】:

      感谢大家的建议,我试试:

      [TestCleanup]
      public void Cleanup()
      {
         CallContext.FreeNamedDataSlot("log4net.Util.LogicalThreadContextProperties");
      }
      

      并且有效!

      【讨论】:

      • 这应该作为评论添加到接受的答案
      • 可能,但它确实很快帮助了我。 :)
      猜你喜欢
      • 1970-01-01
      • 2023-03-27
      • 1970-01-01
      • 2012-01-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多