我已经实现了ASP.net Web服务SoapExtension,并且想对其进行单元测试。问题是我要测试的ProcessMessage()方法中有代码,并且该方法需要SoapMessage作为参数。

给出的SoapMessage是带有内部构造函数的抽象类,并且我所知道的仅有两个派生类(SoapClientMessageSoapServerMessage)是密封的,如何实例化它?

我是使用TypeMockJustMock这样的商业模拟工具的唯一选择吗?

最佳答案

我能想到的最好的方法是使用反射实例化密封的类并在其内部字段中设置值。

这是我想出的代码:

    private SoapServerMessage CreateSoapServerMessage(
        SoapMessageStage stage,
        string action,
        SoapHeaderCollection headers)
    {
        var typ = typeof(SoapServerMessage);

        // Create an instance:
        var constructorInfo = typ.GetConstructor(
            BindingFlags.NonPublic | BindingFlags.Instance,
            null, new[] { typeof(SoapServerProtocol) }, null);
        var message = (SoapServerMessage)constructorInfo.Invoke(new object[] { CreateSoapServerProtocol(action) });

        // Set stage:
        var stageField = typ.BaseType.GetField("stage", BindingFlags.NonPublic | BindingFlags.Instance);
        stageField.SetValue(message, stage);

        // Set headers:
        var headersField = typ.BaseType.GetField("headers", BindingFlags.NonPublic | BindingFlags.Instance);
        headersField.SetValue(message, headers);

        return message;
    }

    private SoapServerProtocol CreateSoapServerProtocol(string action)
    {
        var typ = typeof(SoapServerProtocol);

        // Create an instance:
        var constructorInfo = typ.GetConstructor(
            BindingFlags.NonPublic | BindingFlags.Instance,
            null, Type.EmptyTypes, null);
        var protocol = (SoapServerProtocol)constructorInfo.Invoke(null);

        // Set serverMethod:
        var serverMethodField = typ.GetField("serverMethod", BindingFlags.NonPublic | BindingFlags.Instance);
        serverMethodField.SetValue(protocol, CreateSoapServerMethod(action));

        return protocol;
    }

    private SoapServerMethod CreateSoapServerMethod(string action)
    {
        var typ = typeof(SoapServerMethod);

        // Create an instance:
        var method = new SoapServerMethod();

        // Set action:
        var actionField = typ.GetField("action", BindingFlags.NonPublic | BindingFlags.Instance);
        actionField.SetValue(method, action);

        return method;
    }

关于c# - 如何实例化ASP.net Web服务的SoapMessage?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/37664802/

10-13 04:36