Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 单元测试AppContext开关_.net_Unit Testing_Nunit_Signedxml_Cryptographicexception - Fatal编程技术网

.net 单元测试AppContext开关

.net 单元测试AppContext开关,.net,unit-testing,nunit,signedxml,cryptographicexception,.net,Unit Testing,Nunit,Signedxml,Cryptographicexception,更改日志 重命名的问题:AppContext开关在单元测试中失败(加密异常:指定的算法无效) 在做了更多调查后,在底部添加了一节,进一步详细解释了问题 在底部添加了一节,解释我已经实现的解决方法 我有一段代码,我正在为一些xml编写单元测试 在开发代码时,我注意到.NET 4.7.1+将抛出加密异常:指定的算法无效。为了解决这个问题,我使用了以下AppContext开关(来源:,) 我已将以下代码放入调用我的xml签名代码的任何应用程序中: AppContext.SetSwitch("Swi

更改日志

  • 重命名的问题:AppContext开关在单元测试中失败(加密异常:指定的算法无效)
  • 在做了更多调查后,在底部添加了一节,进一步详细解释了问题
  • 在底部添加了一节,解释我已经实现的解决方法
我有一段代码,我正在为一些xml编写单元测试

在开发代码时,我注意到.NET 4.7.1+将抛出
加密异常:指定的算法无效
。为了解决这个问题,我使用了以下
AppContext
开关(来源:,)

我已将以下代码放入调用我的xml签名代码的任何应用程序中:

AppContext.SetSwitch("Switch.System.Security.Cryptography.Xml.UseInsecureHashAlgorithms", true);
AppContext.SetSwitch("Switch.System.Security.Cryptography.Pkcs.UseInsecureHashAlgorithms", true);
在野外运行时,此代码运行正常,并且我的xml按预期进行了签名

我已经为这段代码编写了一些单元测试,这是我第一次真正尝试编写单元测试,我遇到了一些奇怪的边缘案例

try
{
    // Compute the signature.
    signedXml.ComputeSignature();
}
catch (CryptographicException cex)
{
    //Contains instead of == since this message contains newline characters...
    if (cex.Message.Contains("Invalid algorithm specified"))
    {
        string code = Environment.NewLine + "AppContext.SetSwitch(\"Switch.System.Security.Cryptography.Xml.UseInsecureHashAlgorithms\", true);" +
                        Environment.NewLine + "AppContext.SetSwitch(\"Switch.System.Security.Cryptography.Pkcs.UseInsecureHashAlgorithms\", true); ";

        throw new Exception($"Cryptographic exception was thrown, ensure that the following switches are set in the executing assembly: {code}", cex);
    }
    else
    {
        throw cex;
    }
}
因此,如果抛出异常,我会显示一条很好的消息,说请在调用此方法之前添加以下代码

我的测试类如下所示:

[TestFixture]    
public class XMLSigningTests
{
    protected IXMLSigner _xmlSigner;
    protected byte[] _publicKey;
    protected string _password;

    [SetUp]
    public void Init()
    {
        _xmlSigner = new XMLSigner();
        _password = "test";
        _publicKey = GenerateTestCert(_password);
    }

    [TearDown]
    public void CleanUp()
    {
        _xmlSigner = null;
        _publicKey = null;
        _password = null;
    }

    [Test]
    public void SignXML_AppContextSwitchNotSet_Fail()
    {
        XMLDocument xmlDoc = GenerateXML();

        Assert.Throws<Exception>(() => { _xmlSigner.SignXML(xmlDoc, _publicKey, _password); });
    }

    [Test]
    public void SignXML_AppContextSwitchSet_Success()
    {
        AppContext.SetSwitch("Switch.System.Security.Cryptography.Xml.UseInsecureHashAlgorithms", true);
        AppContext.SetSwitch("Switch.System.Security.Cryptography.Pkcs.UseInsecureHashAlgorithms", true);

        XMLDocument xmlDoc = GenerateXML();

        var signedXml = _xmlSigner.SignXML(xmlDoc, _publicKey, _password); 

        Assert.IsFalse(signedXML == null);
        //More validation here
    }

    private XMLDocument GenerateXML()
    {
        return new XMLDocument("Some fancy xml here...");
    }

    private byte[] GenerateTestCert(string password)
    {
        //Use Pluralsight.Crypto to generate a self signed cert & export as .pfx
        return cert.Export(X509ContentType.Pfx, password);
    }
}
现在,您希望这段代码通过我的失败测试(没有设置开关),它确实通过了,您可以在测试资源管理器中看到我的原始
NotImplementedException
消息。然而,我期望成功的测试再次抛出
加密异常

System.Exception : Cryptographic exception was thrown, ensure that the following switches are set in the executing assembly: 
    AppContext.SetSwitch("Switch.System.Security.Cryptography.Xml.UseInsecureHashAlgorithms", true);
    AppContext.SetSwitch("Switch.System.Security.Cryptography.Pkcs.UseInsecureHashAlgorithms", true); 
      ----> System.Security.Cryptography.CryptographicException : Invalid algorithm specified.
正如我之前所说的,我对测试非常陌生,我不确定我的测试设计方法是否错误,如果我只是在测试一些隐藏的意大利面代码,那么也许我注定要尝试测试它,或者我遗漏了一些东西来正确测试这个案例

我目前正在使用
NUnit 3.12.0+NUnit3TestAdapter 3.15.1
编写测试,尽管我最初使用的是
MSTest 1.3.2
,并且在使用这两个框架时经历了相同的行为


更新 我发现以下测试的执行顺序决定了成功:

  • SignXML\u AppContextSwitchNotSet\u失败
  • SignXML\u AppContextSwitchSet\u成功
我通过阅读诸如()之类的文章发现了这一点,这些文章讨论了在没有单独运行时失败的测试

这让我想到了要设置的值,我想要以下情况:

//Test I expect to fail
AppContext.SetSwitch("the switch..", false);

//Test I expect to pass
AppContext.SetSwitch("the switch..", true);
尽管我已经测试了这些值是否设置正确,但底层交换机是否正在更新?如何清理这些底层对象


解决方案/讨厌的修复 我在上发现了以下问题。在这个线程中,他们讨论了每个测试中新的
AppDomain
选项,这正是我的案例中需要的

下面的一个线程发布了一个util类,在一个单独的
AppDomain
()中运行代码(我不会在这里发布,因为这篇文章已经很庞大了)。我使用了这个util类并调整了测试以使用它(您不能使用任何类变量或方法,这意味着我必须复制我的helper方法代码)

一旦我实现了util并调整了我的测试以符合它的标准,当我单独运行它们时,测试就开始通过这两个测试&一次全部通过


任务完成了

我也有同样的问题! 我偶然发现了这篇文章,它激发了我的解决方案

我没有在单独的AppDomain中运行测试,而是修改了调用加密库的生产代码。 我在一个单独的AppDomain中运行有问题的调用,在继续之前在其中设置开关

这修复了所有的测试,并且使我的库的客户端不会弄乱开关

//Test I expect to fail
AppContext.SetSwitch("the switch..", false);

//Test I expect to pass
AppContext.SetSwitch("the switch..", true);