I have some integration tests where I want to verify certain requires are made against a third-[arty webserver. I was thinking I would replace the third-party server with a stub server that simply logs calls made to it. The calls do not need to succeed, but I do need a record of the requests made (mainly just the path+querystring).
I was considering just using IIS for this. I could 1) set up an empty site, 2) modify the system's host file to redirect requests to that site 3) parse the log file at the end of each test.
This is problematic as for IIS the log files are not written to immediately, and the files are written to continuosly. I'll need to locate the file, read the contents before the test, wait a nondeterministic amount of time after the test, read the update contents, etc.
Can someone think of a simpler way?
I was looking for a solution to the same problem posted above. I have an outgoing http request that connects to an external server, and I wanted to verify the output (XML).
I am using NUnit for my tests. I was having trouble creating a test that is able to receive the output, while at the same time invoking the output logic. Everything I tried would either hang at the sending or receiving part.
Thanks to the answers I found in this post I was able to create a test that worked for me, and I wanted to share it in case it could be useful to someone else.
Fixture:
[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();
}
}
The test:
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);
}
}