4

The setup is as follows:

  • a .NET Standard 2.0 library
  • a NUnit test project for it, targeting .NETFramework 4.6.1

Latest VS 2017, latest NUnit.

I've been working on the project on weekend from home, uploaded my work to git and today started working from work (I've already worked from both places before). Only now I found that something was wrong with the project (I don't remember very well what was wrong at the start, but it seems the problem was the same as I have now, described later).

After fiddling around to unrepairable state with it, I wholly deleted it and cloned the git repo anew.

The project compiles fine, but at runtime tests throw "Method not found" exception. A bit of poking around showed that the problem only manifests on one overload of the following method:

    public static YNABClient GetInstance(HttpMessageHandler _handler)
    {
        if (instance is null)
        {
            instance = new YNABClient(_handler);
        }

        return instance;
    }

    public static YNABClient GetInstance() => GetInstance(new HttpClientHandler());

The one without parameters is fine, the one with is not. Deleting and adding library as a reference to tests, deleting and adding both test and library project. Other solutions for similar situations I found on the internet all pertain to ASP.NET MVC, which is not my case, though this question did lead me to checking overloads and finding that one of them actually works.

At home everything still works fine, though I have yet to try to delete and reinstall the project as I did at work. This leads to 2 possible sources for problems: environment, though I haven't managed to find a meaningful difference, or git, though I use a "stock" git ignore for VS (this one), so there shouldn't be problems there. The basic setup for my projects didn't change during weekend and worked before, so something broke from recent fiddling.

Also, if I add a console application(.Net Framework 4.6.1) to solution and try calling the problematic method from it, it actually works fine.

If that would help, my github for the project is here

I've been asked for calling examples in the comments. Basically, I have 2 Test Fixture classes with different setups - one for real API calling for ease of debugging actual use, and one with faking it, as per good test practices. Works:

    [OneTimeSetUp]
    public void Setup()
    {
        ynabClient = YNABClient.GetInstance();
        ynabClient.RefreshAccessToken(ApiKeys.AccessToken);
    }

Throws exception:

    [OneTimeSetUp]
    public void Setup()
    {
        handler = new StubHandler();
        ynabClient = YNABClient.GetInstance(handler);
    }

Some poking around shows that my problem is quite likely related to System.Net.Http versioning discrepancy with .NET Framework and .NET Standard, that is quite a widespread problem if you google it. However none of the examples I dug up exhibit my particular symptoms, and I'm not yet sure what to do. And why everything works fine on my home PC.

4

3 回答 3

0

您遇到的问题是您的GetInstance方法接受HttpMessageHandler作为参数,并且在您的测试中您正在传递HttpClientHandler对象。因此,您声明了一个参数,但在调用该方法时提供了不同的对象。

于 2018-07-23T15:09:13.483 回答
0

因此,事实证明,正如 DongDong 所建议的那样,问题确实出在 .NET Framework 和 .NET Standard 之间的接口上。问题并不在于它们不兼容,或者测试项目需要一些额外的依赖项,而是它们附带了不同版本的 System.Net.Http。

没有显示任何可见错误,从而阻碍了诊断。但是,更改参数类型确实表明,问题仅出在该命名空间中的类上。

诊断问题的另一个问题是该项目在某些机器上运行良好(我的家用 PC 和 Daisy Shipton 从评论到问题)。

然而,在确定了问题的根源之后,我能够首先在谷歌上搜索该库存在哪些问题,并最终在.NET github上发现了一大堆不兼容问题。

我尝试了在这些情况下使用的解决方案,并将“绑定重定向”添加到库的具体版本,之后它就可以正常工作了。我添加了app.config我的测试项目的重定向。作为参考,它看起来像这样:

<dependentAssembly>
    <assemblyIdentity name="System.Net.Http" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
    <bindingRedirect oldVersion="0.0.0.0-4.2.0.0" newVersion="4.2.0.0" />
</dependentAssembly>

我仍然不明白为什么该项目在某些机器上运行良好。

于 2018-07-24T11:12:43.537 回答
0

我在我的环境中遇到了这个错误:

严重性代码描述项目文件行抑制状态错误 CS0433 类型“HttpMessageHandler”同时存在于“System.Net.Http, Version=4.2.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a”和“System.Net.Http, Version=4.0”中.0.0,文化=中性,PublicKeyToken=b03f5f7f11d50a3a'

YNABConnector是 .NET Standard 2 但单元测试是 4.6.1,它们对同一程序集使用不同的签名。

这是要测试的官方文档: https ://github.com/nunit/docs/wiki/.NET-Core-and-.NET-Standard

  1. 创建了一个 .NET Core 库(请注意:不能通过上述链接成为 .NET Standard 库),
  2. 在那里复制你的测试代码,
  3. 按照官方文档添加引用,

然后您的代码可以正常工作,没有错误。

但是在您的基本代码中,我仍然更喜欢这段代码:

public class YNABClient
{
    private static YNABClient instance;

    private HttpClient client;

    private HttpMessageHandler handler;

    private YNABClient(HttpMessageHandler _handler = null)
    {
        handler = _handler ?? new HttpClientHandler();
        client = new HttpClient(_handler);
    }

    public static YNABClient GetInstance(HttpMessageHandler _handler = null)
    {
        return instance ?? (instance = new YNABClient(_handler));
    }

    ......
}
于 2018-07-23T15:19:20.020 回答