Как реализовать SoapMessage веб-службы ASP.net?
Я реализовал веб-сервис ASP.net SoapExtension
и я хочу проверить его. Беда в том, что у меня есть код в ProcessMessage()
метод, который я хочу проверить, и этот метод ожидает SoapMessage
в качестве аргумента.
Учитывая чем SoapMessage
абстрактный класс с внутренним конструктором и что только два производных класса, которые я знаю (SoapClientMessage
а также SoapServerMessage
) запечатаны, как я могу создать его экземпляр?
Является ли мой единственный вариант использования коммерческих инструментов для насмешки, таких как TypeMock или JustMock?
1 ответ
Лучшее, что я мог придумать, - это использовать отражение для создания экземпляров запечатанных классов и установки значений в их внутренних полях.
Вот код, который я придумал:
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;
}