c# - 特定方法的 CallerMemberName 参数为空

标签 c# unit-testing debugging runtime

我有以下日志方法(用于单元测试项目):

        public static void WriteLogFile<T>(T obj, [System.Runtime.CompilerServices.CallerMemberName] string callingMethod = "")
        {
#if WRITELOGFILE
            var path = Path.Combine(LogFileLocation, callingMethod + ".json");
            var content = (typeof(T) == typeof(string)) ? (obj as string) : JsonConvert.SerializeObject(obj);

            File.WriteAllText(path, content);
#endif
        }

我在下面的 TestMethod 中使用它:

[TestMethod]
public async Task TestGetUserInfoAsync()
{
    //var tokenFile = TestUtils.GetLogFileLocation(nameof(this.TestRedeemTokensAsync2));
    var tokenFile = @"D:\Temp\TestLog\TestRedeemTokensAsync2.json";
    var accessToken = JsonConvert.DeserializeObject<dynamic>(File.ReadAllText(tokenFile))
        .access_token.ToString();

    var result = await GoogleService.GetUserInfoAsync(this.systemConfig,
       accessToken);
    TestUtils.WriteLogFile(result);

    Assert.IsNotNull(result);
}

我还有其他 3 种测试方法,它们都运行正常,它们都有异步/等待任务,使用从方法名称中获取的文件名写入日志文件。

但是,对于上面的具体方法,参数callingMethod是一个空字符串(not null)。结果文件是一个名为 .json 的文件(它是 Windows 中的有效文件)。我不确定这是否仅与单元测试项目有关。

为什么会这样?在这种情况下我该如何调试?

附加信息:我认为可能是因为我添加了下面的方法,第一个调用搞砸了:

public static string GetLogFileLocation([System.Runtime.CompilerServices.CallerMemberName] string callingMethod = "")
{
    var path = Path.Combine(LogFileLocation, callingMethod + ".json");
    return path;
}

但是,我尝试删除它并改用硬字符串作为文件路径(如您在上面的代码中所见),但问题仍然存在。

编辑:我添加了可能有用的堆栈跟踪。我注意到代码之间有一个 [External Code] 行。我不知道是什么原因造成的。

enter image description here

EDIT2:IL 代码确实有问题:其他 4 个(抱歉,是 4 个,不是 3 个)TestMethod 运行良好,它们的 IL 代码是正确的,如下所示:

enter image description here

但是,我遇到问题的方法没有看到任何函数调用。我能看到的唯一 WriteLogFile 是这个,但它是一个字符串:

enter image description here

完整的 IL 代码在这里:http://pasted.co/cf4b0ea7

最佳答案

问题似乎是 asyncdynamic 一起发生的。删除其中一个(切换到同步或转换为强类型变量)修复问题:

[TestMethod]
public async Task TestGetUserInfoAsync()
{
    //var tokenFile = TestUtils.GetLogFileLocation(nameof(this.TestRedeemTokensAsync2));
    var tokenFile = @"D:\Temp\TestLog\TestRedeemTokensAsync2.json";
    var accessToken = (JsonConvert.DeserializeObject<dynamic>(File.ReadAllText(tokenFile))
        .access_token.ToString()) as string; // Here, cast this to string instead of keeping it as dynamic

    var result = await GoogleService.GetUserInfoAsync(this.systemConfig,
       accessToken);
    TestUtils.WriteLogFile(result);

    Assert.IsNotNull(result);
}

关于c# - 特定方法的 CallerMemberName 参数为空,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49361452/

相关文章:

c# - 使用 SharpZipLib 时 - 无法从 MemoryStream 中提取 tar.gz 文件

c# - 编译时禁用 Dll 文化文件夹

C#驱动2.0 Mongodb UpdateOneAsync

angular - 类型错误 : Cannot read property 'get' of undefined (Fixed conflicting imports not working)

C++ 运算符重载和继承

windows - 在 Windows 8.1 中将调试器附加到 Services.exe

c# - ASP.NET MVC 5 从 TMDB API 获取 JSON 结果

c# - 如何使用 ExpectedException 属性强制执行异常消息

C# 单元测试 : Testing a method that uses MapPath

debugging - 如何检查失败的 `docker build` 的文件系统?