This may sound stupid, but I just can't catch an ExtendedSocketException that is getting thrown by SocketTaskExtensions.ConnectAsync().
The full namespace is: System.Net.Internals.SocketExceptionFactory.ExtendedSocketException
The compiler complains with Cannot resolve symbol 'ExtendedSocketException'. Both my class library and test projects are targeting .Net Core 2.1.
Also there is no such reference or Nuget package that could be added. At least I coudn't find anything... Also there seems nothing on https://learn.microsoft.com...
What am I doing wrong here?
[Fact]
[Trait("Category", "UnitTest")]
public async Task Should_Throw_Exception_If_Port_Unreachable()
{
// Arrange
var client = new TcpConnector();
var nonListeningPort = 81;
var endpoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), nonListeningPort);
// Act & Assert
var connectTask = client.ConnectAsync(endpoint);
Func<Task> func = async () => { await connectTask; };
func.Should().Throw<ExtendedSocketException>();
}
ExtendedSocketException is a private class so you can't reference it outside of .NET internals. You can catch SocketException however and inspect the exception message.
Even though the ExtendedSocketException is meant to be private, it's definitely being exposed:
On the other hand, it inherits from SocketException, so we shouldn't need to care about it too much.
In terms of your test, I assume that you should be able to modify your assertion to something similar to:
var exception = Assert.Catch(func);
Assert.IsInstanceOf<SocketException>(exception);
Assert.That(exception.Message.Contains("actively refused"));
ExtendedSocketException is derived from SocketException (for .NET Core). This can still be handled by using a catch block catching SocketException. We are able to confirm this through System.Type.IsAssignableFrom(Type c):
catch (Exception e)
{
Debug.Write(typeof(SocketException).IsAssignableFrom(e.GetType()));
}
In xUnit, the assertion can be:
var client = new TcpClient();
Task result() => client.ConnectAsync(IPAddress.Loopback, 23000);
var ex = Record.ExceptionAsync(async () => await client.ConnectAsync(IPAddress.Loopback, 23000));
Assert.IsAssignableFrom<SocketException>(ex.Result);
Related
Does anyone know why I sometimes get exception when I use Selenium together with Testcontainers. See below:
Exception has occurred: CLR/OpenQA.Selenium.WebDriverException
An exception of type 'OpenQA.Selenium.WebDriverException' occurred in WebDriver.dll but was not handled in user code: 'An unknown exception was encountered sending an HTTP request to the remote WebDriver server for URL http://localhost:4444/session. The exception message was: An error occurred while sending the request.'
Inner exceptions found, see $exception in variables window for more details.
Innermost exception System.IO.IOException : The response ended prematurely.
at System.Net.Http.HttpConnection.d__61.MoveNext()
This happens half the time when i run the following test constructor (C# / xUnit.net):
public DockerShould()
{
var gridNetwork = new NetworkBuilder()
.WithName("gridNetwork")
.Build();
const int SessionPort = 4444;
var containerHub = new ContainerBuilder()
.WithImage("selenium/hub:4.8")
.WithName("selenium-hub")
.WithPortBinding(4442, 4442)
.WithPortBinding(4443, 4443)
.WithPortBinding(SessionPort, SessionPort)
.WithNetwork(gridNetwork)
.Build();
var firefoxEnvironment = new Dictionary<string, string>()
{
{"SE_EVENT_BUS_HOST", "selenium-hub"},
{"SE_EVENT_BUS_PUBLISH_PORT", "4442"},
{"SE_EVENT_BUS_SUBSCRIBE_PORT", "4443"}
};
var containerFirefox = new ContainerBuilder()
.WithImage("selenium/node-firefox:4.8")
.WithEnvironment(firefoxEnvironment)
.WithNetwork(gridNetwork)
.Build();
var firefoxVideoEnvironment = new Dictionary<string, string>()
{
{"DISPLAY_CONTAINER_NAME", "firefox"},
{"FILE_NAME", "firefox.mp4"}
};
var containerFirefoxVideo = new ContainerBuilder()
.WithImage("selenium/video:ffmpeg-4.3.1-20230210")
.WithNetwork(gridNetwork)
.WithEnvironment(firefoxVideoEnvironment)
// .WithWaitStrategy(Wait.ForUnixContainer().UntilPortIsAvailable(SessionPort))
.Build();
gridNetwork.CreateAsync().Wait();
containerHub.StartAsync().Wait();
containerFirefox.StartAsync().Wait();
containerFirefoxVideo.StartAsync().Wait();
Thread.Sleep(5000);
_remoteWebDriver = new RemoteWebDriver(new Uri("http://localhost:4444"), new FirefoxOptions());
}
The exception occurs when creating the new RemoteWebDriver. I've added a thread.sleep to give a bit of a delay before the variable is created. I'm not sure it's really helping much. Is there a more elegant way to ensure all containers are started up before attempting to create the web driver (which i'm assuming is the problem)?
Your configuration has a few shortcomings. I am uncertain as to which one is ultimately causing the issue, but I have provided a working example below. The crucial parts have been commented. Please note that the example does not incorporate a wait strategy to determine the readiness of the container or the service inside it. That is an aspect that you will still need to address. But first lets take a look at some basics.
Please consider reading the article Consuming the Task-based Asynchronous Pattern. Testcontainers for .NET utilizes the Task-based Asynchronous Pattern (TAP). I noticed that you tend to block the asynchronous context frequently.
You do not need to bind ports for container-to-container communication.
Avoid using fixed port bindings such as WithPortBinding(4444, 4444). To prevent port conflicts, assign a random host port by using WithPortBinding(4444, true) and retrieve it from the container instance using GetMappedPublicPort(4444).
Do not use fixed container names for the same reason mentioned in 3. Use WithNetworkAliases(string) instead.
Do not use localhost to access services running inside containers. The endpoint varies according to the Docker environment. Use the Hostname property instead.
public sealed class StackOverflow : IAsyncLifetime
{
private const ushort WebDriverPort = 4444;
private readonly INetwork _network;
private readonly IContainer _selenium;
private readonly IContainer _firefox;
private readonly IContainer _ffmpg;
public StackOverflow()
{
_network = new NetworkBuilder()
.Build();
_selenium = new ContainerBuilder()
.WithImage("selenium/hub:4.8")
// Use random assigned host ports to access the service running inside the containers.
.WithPortBinding(WebDriverPort, true)
.WithNetwork(_network)
// Use a network-alias to communication between containers.
.WithNetworkAliases(nameof(_selenium))
.Build();
_firefox = new ContainerBuilder()
.WithImage("selenium/node-firefox:4.8")
.WithEnvironment("SE_EVENT_BUS_HOST", nameof(_selenium))
.WithEnvironment("SE_EVENT_BUS_PUBLISH_PORT", "4442")
.WithEnvironment("SE_EVENT_BUS_SUBSCRIBE_PORT", "4443")
.WithNetwork(_network)
.WithNetworkAliases(nameof(_firefox))
.Build();
_ffmpg = new ContainerBuilder()
.WithImage("selenium/video:ffmpeg-4.3.1-20230210")
.WithEnvironment("DISPLAY_CONTAINER_NAME", nameof(_firefox))
.WithEnvironment("FILE_NAME", nameof(_firefox) + ".mp4")
.WithNetwork(_network)
.WithNetworkAliases(nameof(_ffmpg))
.Build();
}
public async Task InitializeAsync()
{
await _network.CreateAsync()
.ConfigureAwait(false);
// You can await Task.WhenAll(params Task[]) too.
await _selenium.StartAsync()
.ConfigureAwait(false);
await _firefox.StartAsync()
.ConfigureAwait(false);
await _ffmpg.StartAsync()
.ConfigureAwait(false);
}
public async Task DisposeAsync()
{
await _selenium.DisposeAsync()
.ConfigureAwait(false);
await _firefox.DisposeAsync()
.ConfigureAwait(false);
await _ffmpg.DisposeAsync()
.ConfigureAwait(false);
await _network.DeleteAsync()
.ConfigureAwait(false);
}
[Fact]
public async Task Question()
{
// TODO: The container configurations mentioned above lack a wait strategy. It is crucial that you add a wait strategy to each of them to determine readiness (afterwards remove this line).
await Task.Delay(TimeSpan.FromSeconds(15))
.ConfigureAwait(false);
// Use the Hostname property instead of localhost. Get the random assigned host port with GetMappedPublicPort(ushort).
var webDriver = new RemoteWebDriver(new UriBuilder(Uri.UriSchemeHttp, _selenium.Hostname, _selenium.GetMappedPublicPort(WebDriverPort)).Uri, new FirefoxOptions());
Assert.NotNull(webDriver.SessionId);
}
}
I will like to ask you please: What do you use hub and node selenium mode?
I recommended using in this case standalone mode - and why?
Because the webDriver testcoaniner in my opinion works like a dynamic grid in s: docker-selenium github
I am also asking because I just working on that: Feature- WebDriver container
So I would like your opinion and how I can map between the testcotanienr and the RemoteWebDriver capabilities
I have a method in my c# application similar to below.
public async Task SampleMethod()
{
try
{
//some code
await AnotherMethod();
// some code
}
catch (Exception ex)
{
Console.Error.WriteLine(ex.Message.ToString());
}
}
Now, I'm trying to write a unit testcase for the above method using MStest. I have written something as below.
[TestMethod]
public async Task SampleMethodTest()
{
ClassName cn = new ClassName();
await cn.SampleMethod();
}
Now how do I know if the testcase failed or succeeded. How do I use Assert here?
Any help is highly appreciated.
Based on our comments in my other answer, i try to show you how to get the console output. That you can read all text from console you have to set a StringWriter() to the console:
[TestMethod]
public async Task SampleMethodTest()
{
using (StringWriter stringWriter = new StringWriter())
{
Console.SetOut(stringWriter);
ClassName cn = new ClassName();
await cn.SampleMethod();
string consoleOutput = stringWriter.ToString();
Assert.IsFalse(consoleOutput.Contains("Exception"));
}
}
I hope this works. I haven't tried it with a UnitTest, only with a console program.
If you test the AnotherMethod directly, you will see if it's succefull. When it throws an Exception the test is failed. The SampleMethod does only implement the try catch and calls the AnotherMethod() which can be tested directly.
[TestMethod]
public async Task SampleMethodTest()
{
ClassName cn = new ClassName();
await cn.AnotherMethod();
}
This test fail if it throws an Execption. When the method do not throw an Exception, it is successfull.
If your method changes the state of the object, you can verify if the state of the object is like expected. If not you can use a Mock (with a Framework like Moq) to verify the collaboration with other objects. Note that you maybe need to extract AnotherMethod to another class, so that you can mock and verify the call.
Also note that you should try to design your Software so that you can use Outputverification and Stateverification in most UnitTests. Communication Verification with mocks can lead to false postives and UnitTests that are hard to maintain.
I'm building simple tool for downloading .lua files from online public GitHub repos via link given by user. I started learning async methods so I wanted to test myself.
It's a console application (for now). The ultimate goal is to get .lua files in a repo and ask the user which ones he wants downloaded, but I'll be happy if I connect to GH for now.
I'm using Octokit (https://github.com/octokit/octokit.net) GitHub API integration to .NET.
This is the reduced code; I removed some of unimportant stuff:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Octokit;
namespace GetThemLuas
{
class Program
{
static readonly GitHubClient Github = new GitHubClient(new ProductHeaderValue ("Testing123"), new Uri("https://www.github.com/"));
static void Main(string[] args)
{
Console.WriteLine("Welcome to GitHub repo downloader");
GetRepoTry4();
}
private static async void GetRepoTry4()
{
try
{
Console.WriteLine("Searching for data"); //returns here... code below is never ran
var searchResults = await Github.Search.SearchRepo(new SearchRepositoriesRequest("octokit"));
if (searchResults != null)
foreach (var result in searchResults.Items)
Console.WriteLine(result.FullName);
Console.WriteLine("Fetching data...."); //testing search
var myrepo = await Github.Repository.Get("Haacked", "octokit.net");
Console.WriteLine("Done! :)");
Console.WriteLine("Repo loaded successfully!");
Console.WriteLine("Repo owner: " + myrepo.Owner);
Console.WriteLine("Repo ID: " + myrepo.Id);
Console.WriteLine("Repo Date: " + myrepo.CreatedAt);
}
catch (Exception e)
{
Console.WriteLine("Ayyyy... troubles"); //never trigged
Console.WriteLine(e.Message);
}
}
}
}
The problem is the await` keyword as it terminates the method and returns.
I'm still learning async methods so it's possible I messed something up, but even my ReSharper says it fine.
I used var to replace task<T> stuff. It seams OK to me plus no warnings nor errors.
I fixed the await issue. Now when I finally connected to GH and tried to get the repo it threw an exeption at both calls to GH (tested with commenting first then second call). e.message was some huge stuff.
I logged it into a file and it looks like an HTML document. Here it is (http://pastebin.com/fxJD1dUb)
Change GetRepoTry4(); to Task.Run(async () => { await GetRepoTry4(); }).Wait(); and private static async void GetRepoTry4() to private static async Task GetRepoTry4().
This should get you at least wired up correctly enough to start debugging the real issue.
Generally speaking all async methods need to return a Task or Task<T> and all methods that return a Task or Task<T> should be async. Additionally, you should get your code into the dispatcher as quickly as possible and start using await.
The constructor with the Uri overload is intended for use with GitHub Enterprise installations, e.g:
static readonly GitHubClient Github = new GitHubClient(new ProductHeaderValue ("Testing123"), new Uri("https://github.enterprise.com/"));
If you're just using it to connect to GitHub, you don't need to specify this:
static readonly GitHubClient Github = new GitHubClient(new ProductHeaderValue ("Testing123"));
You're seeing a HTML page because the base address is incorrect - all of the API-related operations use api.github.com, which is the default.
Install Octokit Nuget Package for Github.Then add below function
public JsonResult GetRepositoryDeatil(long id)
{
var client = new GitHubClient(new ProductHeaderValue("demo"));
var tokenAuth = new Credentials("xxxxxxx"); // NOTE: not real token
client.Credentials = tokenAuth;
var content = client.Repository.Content.GetAllContents(id).Result;
List<RepositoryContent> objRepositoryContentList = content.ToList();
return Json(objRepositoryContentList, JsonRequestBehavior.AllowGet);
}
Due to the use of the async/await you should change the definition of the method GetRepoTry4 to the following:
private static async Task GetRepoTry4()
EDIT:
Then in the Main method call it like so GetRepoTry4().Wait();. This will enable the method GetRepoTry4() to be awaited.
I'm looking for some advice on writing some unit tests for the code below. Implementation aside (it's not my code, but I've been tasked to retroactively write some tests for it) could someone suggest how I might test this? I'm not using nUnit or a similar framework; I am using the testing tools built into Visual Studio.
I'm fairly new to writing unit tests, but I imagine I should at least test the following:
Valid response passed into SaveFormBrokerResponse() method
Test for valid exceptions thrown by the catch()
Testing the started Task, but not sure how to do this
I've stripped just a bit out of this function, mostly to do with instantiation and population of some objects:
public void SaveResponse(IForm form, bool isLive, HttpRequestBase request)
{
try
{
var response = new FormBrokerResponses();
// Initialize some vars on response
using (var memory = new MemoryStream())
{
var serializer = new DataContractSerializer(typeof(FormKeyValue[]));
serializer.WriteObject(memory, request.Form.AllKeys.Select(r => new FormKeyValue(r, request.Form[r])).ToArray());
memory.Flush();
memory.Seek(0, SeekOrigin.Begin);
response.Values = Encoding.UTF8.GetString(memory.ToArray());
}
_dataHandler.SaveFormBrokerResponses(response);
}
catch (Exception ex)
{
throw new Exception("boom explosions");
}
Task.Factory.StartNew(() => DispatchFormResponseViaEmail(form, isLive, request.Form.AllKeys.ToDictionary(r => r, r => (object)request.Form[r])));
}
I realize that testing void implementations is tricky and questionable and that there are some integration test concerns here, but that said I can't (currently) change the implementation and need to write tests for what I have.
You can't. You've created a method that fires off an asynchronous operation and then doesn't expose any means of observing the completion/results of that operation to the caller. There are lots of ways of doing this (returning a task, accepting a callback, an event, etc.) but you need to do something for the caller to be able to observe the results of the asynchronous operation. If the method doesn't expose anything, then there is nothing that the caller can reliably do.
If you are allowed to make slight modifications to the code I would do the following which is just a small change anyway :
public void SaveResponse(IForm form, bool isLive, HttpRequestBase request)
{
try
{
var response = new FormBrokerResponses();
// Initialize some vars on response
using (var memory = new MemoryStream())
{
var serializer = new DataContractSerializer(typeof(FormKeyValue[]));
serializer.WriteObject(memory, request.Form.AllKeys.Select(r => new FormKeyValue(r, request.Form[r])).ToArray());
memory.Flush();
memory.Seek(0, SeekOrigin.Begin);
response.Values = Encoding.UTF8.GetString(memory.ToArray());
}
_dataHandler.SaveFormBrokerResponses(response);
}
catch (Exception ex)
{
throw new Exception("boom explosions");
}
Dispatch(form,isLive,request);
}
virtual void Dispatch(IForm form, bool isLive, HttpRequestBase request){
Task.Factory.StartNew(() => DispatchFormResponseViaEmail(form, isLive, request.Form.AllKeys.ToDictionary(r => r, r => (object)request.Form[r])));
}
I don't know what this class is named so suppose the class is named DutClass, you can now derive a different implementation of that class as following:
public class UnitTestClass : DutClass{
override Dispatch(){
//don't do anything or set a state variable that this method was called
}
}
Then instead of testing the DutClass you test the UnitTextClass which has a different implementation of the Dispatch method and does not start a Task at all. You can then test that in fact this method was called, test for the exceptions and so on.
I'm writing a unit test for this one method which returns "void". I would like to have one case that the test passes when there is no exception thrown. How do I write that in C#?
Assert.IsTrue(????)
(My guess is this is how I should check, but what goes into "???")
I hope my question is clear enough.
Your unit test will fail anyway if an exception is thrown - you don't need to put in a special assert.
This is one of the few scenarios where you will see unit tests with no assertions at all - the test will implicitly fail if an exception is raised.
However, if you really did want to write an assertion for this - perhaps to be able to catch the exception and report "expected no exception but got this...", you can do this:
[Test]
public void TestNoExceptionIsThrownByMethodUnderTest()
{
var myObject = new MyObject();
try
{
myObject.MethodUnderTest();
}
catch (Exception ex)
{
Assert.Fail("Expected no exception, but got: " + ex.Message);
}
}
(the above is an example for NUnit, but the same holds true for MSTest)
In NUnit, you can use:
Assert.DoesNotThrow(<expression>);
to assert that your code does not throw an exception. Although the test would fail if an exception is thrown even if there was no Assert around it, the value of this approach is that you can then distinguish between unmet expectations and bugs in your tests, and you have the option of adding a custom message that will be displayed in your test output. A well-worded test output can help you locate errors in your code that have caused a test to fail.
I think it's valid to add tests to ensure that your code is not throwing exceptions; for example, imagine you are validating input and need to convert an incoming string to a long. There may be occasions when the string is null, and this is acceptable, so you want to ensure that the string conversion does not throw an exception. There will therefore be code to handle this occasion, and if you haven't written a test for it you will be missing coverage around an important piece of logic.
This helper class scratched my itch with MSTest. Maybe it can scratch yours also.
[TestMethod]
public void ScheduleItsIneligibilityJob_HasValid_CronSchedule()
{
// Arrange
var factory = new StdSchedulerFactory();
IScheduler scheduler = factory.GetScheduler();
// Assert
AssertEx.NoExceptionThrown<FormatException>(() =>
// Act
_service.ScheduleJob(scheduler)
);
}
public sealed class AssertEx
{
public static void NoExceptionThrown<T>(Action a) where T:Exception
{
try
{
a();
}
catch (T)
{
Assert.Fail("Expected no {0} to be thrown", typeof(T).Name);
}
}
}
Don't test that something doesn't happen. It's like assuring that code doesn't break. That's sort of implied, we all strive for non-breaking, bug-less code. You want to write tests for that? Why just one method? Don't you want all your methods being tested that they don't throw some exception? Following that road, you'll end up with one extra, dummy, assert-less test for every method in your code base. It brings no value.
Of course, if your requirement is to verify method does catch exceptions, you do test that (or reversing it a bit; test that it does not throw what it is supposed to catch).
However, the general approach/practices remain intact - you don't write tests for some artificial/vague requirements that are out of scope of tested code (and testing that "it works" or "doesn't throw" is usually an example of such - especially in scenario when method's responsibilities are well known).
To put it simple - focus on what your code has to do and test for that.
I like to see an Assert.Whatever at the end of each test, just for consistency... without one, can I really be sure there's not supposed to be one there?
For me, this is as simple as putting Assert.IsTrue(true);
I know I didn't accidentally put that code in there, and thus I should be confident enough at quick a skim through that this was as intended.
[TestMethod]
public void ProjectRejectsGappedVersioningByDefault() {
var files = new List<ScriptFile>();
files.Add(ScriptProjectTestMocks.GetVersion1to2());
files.Add(ScriptProjectTestMocks.GetVersion3to4());
Assert.Throws<ScriptProject.InvalidProjectFormatException>(() => {
var sut = new ScriptProject(files);
});
}
[TestMethod]
public void ProjectAcceptsGappedVersionsExplicitly() {
var files = new List<ScriptFile>();
files.Add(ScriptProjectTestMocks.GetVersion1to2());
files.Add(ScriptProjectTestMocks.GetVersion3to4());
var sut = new ScriptProject(files, true);
Assert.IsTrue(true); // Assert.Pass() would be nicer... build it in if you like
}
My friend Tim told me about ExpectedException. I really like this b/c it is more succinct, less code, and very explicit that you are testing for an exception.
[TestMethod()]
[ExpectedException(typeof(System.Exception))]
public void DivideTest()
{
int numerator = 4;
int denominator = 0;
int actual = numerator / denominator;
}
You can read way more about it here: ExpectedException Attribute Usage.
With Xunit you can use this:
var exception = Record.Exception(() =>
MethodUnderTest());
Assert.Null(exception);
or for async operations
var exception = await Record.ExceptionAsync(async () =>
await MethodUnderTestAsync());
Assert.Null(exception);
Another way which worked for me is to store it in a variable and check output.
var result = service.Run()
Assert.IsFalse(result.Errors.Any())
using Moq;
using Xunit;
[Fact]
public void UnitTest_DoesNotThrow_Exception()
{
var builder = new Mock<ISomething>().Object;
//Act
var exception = Record.Exception(() => builder.SomeMethod());
//Assert
Assert.Null(exception);
}