You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用微软测试工具单元测试SOAP请求XML处理方法并模拟请求

问题描述

需要测试一个从SOAP Body中提取并格式化请求XML的静态方法GetSoapXmlRequest,该方法依赖HttpContext.Current.Request.InputStream获取SOAP请求,当前编写的测试未正确模拟请求内容,无法验证方法逻辑。

待测试方法代码:

public static string GetSoapXmlRequest()
{
    XmlDocument xmlSoapRequest = new XmlDocument();
    string strFormatedXML = string.Empty;
    try
    {
        Logger.Info("-----------Starting of GetSoapXmlRequest method Call-------");
        Logger.Info(MethodBase.GetCurrentMethod().ToString());
        using (Stream receiveStream = HttpContext.Current.Request.InputStream)
        {
            if (receiveStream.Position > 0)
            {
                receiveStream.Position = 0;
            }
            using (StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF8))
            {
                xmlSoapRequest.Load(readStream);
            }
        }
        Logger.Info(AsString(xmlSoapRequest));
        if (xmlSoapRequest.ChildNodes.Count > 0)
        {
            XDocument xmlInputSoapRequest = XDocument.Parse(xmlSoapRequest.OuterXml);
            XElement soapAuthToken = xmlInputSoapRequest.Root.Elements().FirstOrDefault();
            XElement soapBody = xmlInputSoapRequest.Root.Elements().LastOrDefault();
            XmlReader readerSoapAuthToken = soapAuthToken.CreateReader();
            var xmlSoapAuthToken = XDocument.Load(readerSoapAuthToken);
            XmlReader readerSoapBody = soapBody.CreateReader();
            var xmlSoapBody = XDocument.Load(readerSoapBody);
            xmlSoapAuthToken.Root.Add(xmlSoapBody.Root.Elements());
            strFormatedXML = xmlSoapAuthToken.ToString();
        }
        Logger.Info(strFormatedXML);
        Logger.Info("-----------End of GetSoapXmlRequest method Call-------");
        return strFormatedXML;
    }
    catch (Exception)
    {
        return string.Empty;
    }
}

用户尝试的测试方法:

[TestMethod]
public void GetSoapXmlRequest_PostUCCValidationResult_ReturnsTrue()
{
    var req = new HttpRequest("", "http://tempuri.org", "");
    HttpContext.Current = new HttpContext(req, new HttpResponse(new StringWriter()));
    string soapRequest = Utility.GetSoapXmlRequest();
    Assert.AreEqual(true, string.IsNullOrEmpty(soapRequest));
}
解决方案

完成单元测试的核心是模拟包含SOAP请求内容的HttpRequest.InputStream,并验证方法返回的格式化XML是否符合预期。

1. 构造测试用的SOAP请求XML

准备一个符合结构的SOAP示例,包含Envelope、Header(AuthToken节点)和Body:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Header>
    <AuthToken xmlns="http://example.com/auth">
      <Token>abc123</Token>
    </AuthToken>
  </soap:Header>
  <soap:Body>
    <UCCValidationResult xmlns="http://example.com/services">
      <Result>Success</Result>
      <UCCCode>123456789</UCCCode>
    </UCCValidationResult>
  </soap:Body>
</soap:Envelope>

2. 模拟HttpRequest的InputStream

将SOAP XML转换为字节流,写入HttpRequest的InputStream中,同时重置流的位置确保方法能正确读取。

3. 完善测试方法

修改测试代码,添加流模拟逻辑,并断言返回结果是否符合预期(即AuthToken节点包含Body中的子元素):

[TestMethod]
public void GetSoapXmlRequest_ValidSoapRequest_ReturnsFormattedXml()
{
    // 1. 构造测试用的SOAP XML字符串
    string soapXml = @"<soap:Envelope xmlns:soap=""http://schemas.xmlsoap.org/soap/envelope/"">
                          <soap:Header>
                            <AuthToken xmlns=""http://example.com/auth"">
                              <Token>abc123</Token>
                            </AuthToken>
                          </soap:Header>
                          <soap:Body>
                            <UCCValidationResult xmlns=""http://example.com/services"">
                              <Result>Success</Result>
                              <UCCCode>123456789</UCCCode>
                            </UCCValidationResult>
                          </soap:Body>
                        </soap:Envelope>";

    // 2. 将XML字符串转换为字节流
    byte[] soapBytes = Encoding.UTF8.GetBytes(soapXml);
    MemoryStream inputStream = new MemoryStream(soapBytes);

    // 3. 创建模拟的HttpRequest并设置InputStream
    var req = new HttpRequest("", "http://tempuri.org", "");
    req.InputStream = inputStream;
    // 重置流位置(避免方法读取时位置在末尾)
    inputStream.Position = 0;

    // 4. 设置HttpContext.Current
    HttpContext.Current = new HttpContext(req, new HttpResponse(new StringWriter()));

    // 5. 调用待测试方法
    string result = Utility.GetSoapXmlRequest();

    // 6. 断言结果:验证返回的XML包含AuthToken和Body中的子元素
    Assert.IsFalse(string.IsNullOrEmpty(result));
    Assert.IsTrue(result.Contains("<Token>abc123</Token>"));
    Assert.IsTrue(result.Contains("<Result>Success</Result>"));
    Assert.IsTrue(result.Contains("<UCCCode>123456789</UCCCode>"));
}

额外优化建议

  • 降低耦合度:原方法直接依赖静态的HttpContext.Current,测试耦合度高。建议修改方法,将HttpRequest作为参数传入,比如:
    public static string GetSoapXmlRequest(HttpRequest request)
    {
        // 方法逻辑中使用传入的request,而非HttpContext.Current.Request
    }
    
    测试时无需设置HttpContext.Current,直接传入模拟的HttpRequest即可,测试更简洁。
  • 覆盖异常分支:补充测试用例,模拟读取流失败、XML格式错误等场景,验证方法是否返回空字符串。

内容的提问来源于stack exchange,提问作者LogicalDesk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 07:05:00