iis 用于集成测试的存根Web服务器

vsdwdz23  于 12个月前  发布在  其他
关注(0)|答案(4)|浏览(91)

我有一些集成测试,我想验证对第三方服务器的某些要求。我想用一个存根服务器来取代第三方服务器,它只记录对它的调用。调用不需要成功,但我需要记录所发出的请求(主要是路径+querystring)。
我在考虑使用IIS来实现这个功能,我可以1)设置一个空站点,2)修改系统的主机文件以将请求重定向到该站点,3)在每次测试结束时解析日志文件。
这是有问题的,因为IIS的日志文件不会立即写入,文件会持续写入。我需要找到文件,在测试前读取内容,在测试后等待不确定的时间,读取更新内容等。
有人能想到更简单的方法吗?

htzpubme

htzpubme1#

您可以使用System.Net.HttpRequest(MSDN LINK)。
它作为嵌入式Web服务器工作,这意味着您甚至可以检查访问,而无需解析日志文件。
我最近在代码中使用的一个类:

class Listener
{
    private HttpListener listener = null;

    public event EventHandler CommandReceived;

    public Listener()
    {
        this.listener = new HttpListener();
        this.listener.Prefixes.Add("http://localhost:12345/");
    }

    public void ContextReceived(IAsyncResult result)
    {
        if (!this.listener.IsListening)
        {
            return;
        }
        HttpListenerContext context = this.listener.EndGetContext(result);
        this.listener.BeginGetContext(this.ContextReceived, this.listener);

        if (context != null)
        {
            EventHandler handler = this.CommandReceived;
            handler(context, new EventArgs());
        }
    }

    public void Start()
    {
        this.listener.Start();
        this.listener.BeginGetContext(this.ContextReceived, this.listener);
    }

    public void Stop()
    {
        this.listener.Stop();
    }
}

字符串

q8l4jmvw

q8l4jmvw2#

我正在寻找解决上面发布的相同问题的方法。我有一个连接到外部服务器的传出http请求,我想验证输出(XML)。
我正在使用NUnit进行测试。我在创建一个能够接收输出的测试时遇到了麻烦,同时调用输出逻辑。我尝试的所有内容都将在发送或接收部分挂起。
感谢我在这篇文章中找到的答案,我能够创建一个适合我的测试,我想分享它,以防它对其他人有用。
固定装置:

[NonParallelizable]
public abstract class ListenerFixture : MyNormalFixture
{
    protected readonly string ListenerUrl = $"http://{IPAddress.Loopback}:1234/";
    protected IAsyncResult CallbackContext = null!;
    protected XDocument CallbackResult = new();
    private readonly HttpListener _listener;

    protected ListenerFixture()
    {
        _listener = new HttpListener();
        _listener.Prefixes.Add(ListenerUrl);
    }

    [SetUp]
    public override async Task SetUp()
    {
        await base.SetUp();
        
        _listener.Start();
        
        CallbackContext = _listener.BeginGetContext(ListenerCallback, _listener);
    }

    [TearDown]
    public override async Task TearDown()
    {
        _listener.Stop();

        await base.TearDown();
    }

    [OneTimeTearDown]
    public void OneTimeTearDown()
    {
        _listener.Close();
    }
    
    private void ListenerCallback(IAsyncResult result)
    {
        if (!_listener.IsListening)
        {
            return;
        }
    
        var context = _listener.EndGetContext(result);
        
        var resultString = new StreamReader(context.Request.InputStream).ReadToEnd();
        CallbackResult = XDocument.Parse(resultString);
        
        context.Response.Close();
    }
}

字符串
测试:

internal class SendXmlShould : ListenerFixture
{
    [Test, Timeout(10000)]
    public async Task SendXml()
    {
        // Arrange
        var expected = XDocument.Load("TestData/test-output.xml");
        
        /* Some setup for the output logic */
        
        // Act
        await /*Invoke the output logic*/;
        CallbackContext.AsyncWaitHandle.WaitOne();

        // Assert
        CallbackResult.Should().BeEquivalentTo(expected);
    }
}

bfhwhh0e

bfhwhh0e3#

是的,我不认为你需要一个完整的网络服务器。你不需要测试HTTP。
你需要测试的是你发送和接收的底层数据结构。所以只需要为它创建测试(即,确定一个点,在这个点上你可以验证你生成的数据格式与预期的数据格式,以及你打算接收的数据格式等)。
测试数据,而不是测试协议(除非协议是自定义的)。

aiazj4mn

aiazj4mn4#

我在很多项目中做过类似的事情。
你不想创建stubbed web服务。那只是添加一个你不需要的依赖项。我所做的是创建一个模拟web服务的API的接口。然后我创建了一个代理类,它将在实时系统中调用web服务。为了测试,我使用RhinoMocks创建了一个模拟类,它将返回我想要测试的结果。这对我非常有用。因为我可以产生各种各样的“意想不到的”行为,这将是不可能的生活系统。

public interface IServiceFacade {
    string Assignments();
}

public class ServiceFacade : IServiceFacade {
    private readonly Service _service;

    public ServiceFacade(Service service) {
        _service = service;
    }

    public string Assignments() {
        return _service.Assignments();
    }
}

字符串
然后我的测试代码包含这样的内容:

var serviceFacade = MockRepository.GenerateMock<IServiceFacade>();
        serviceFacade.Stub(sf => sf.Assignments()).Return("BLAH BLAH BLAH");


serviceFacade.Stub(sf => sf.Assignments()).Return(null);


serviceFacade.Stub(sf => sf.Assignments()).Throw(new Exception("Some exception"));


我发现这个很有用。

相关问题