I am trying to test some async methods involving the HttpClient work with vs 2012 express for win 8 and it's test framework. No matter how I try I always get the same exception.
For example this test code:
[TestMethod]
public async Task Connect()
{
HttpClient client = new HttpClient();
string reply = await client.GetStringAsync("http://google.com");
Assert.AreNotEqual(0, reply.Length);
}
Which should probably work considering this: http://www.richard-banks.org/2012/03/how-to-unit-test-async-methods-with.html
Throws
System.Net.WebException: The remote name could not be resolved: 'google.com'
The same code works just fine when called from an actual program (not a test case).
Any help is appreciated.
Please refer to my comments and I can include this as an answer to your question.
"Are you are using the metro style Unit Testing template? If yes you need to enable the Internet Client (I think) in the app manifest file -> capabilities to allow this behaviour?. Also since you are testing an external call, this is not a Unit Test. It is more of an integration test."
I have used exactly the same code you have and I get exactly the same error. As I said if you just tick the the Package.appxmanifest -> Capabilities - > Internet (Client) check box, you test should pass.
Related
I've been trying to look for examples on the internet or anywhere of how to implement gRPC unit testing in c# but can't for the love of me find anything, or I could just be over seeing things.
If someone could point me in the right direction I would be very grateful.
S
For simple unary services, as long as you're not doing anything interesting with gRPC headers, cancellation, etc - you should be able to treat your server type just as the service type - create an instance, call the simple unary method(s), check the results. However, this won't validate marshalling or the gRPC layer, etc. For that, you really need an integration test. Likewise, anything involving streaming probably needs an integration test, because there's a lot of background plumbing. If this was me, I would simply create a server as a test-fixture, and write my tests by creating a genuine client that can talk to those services.
If you're using the Google server code, something like the fixture I'm using here should do (don't worry about the AddCodeFirst - that's some protobuf-net.Grpc additions; just use the same registration code that you would have used in the real server). If you need to test with the Microsoft server code, you'd need to host Kestrel in process as the fixture; but fortunately: they're mostly completely interchangeable, so if in doubt: use whichever is simpler. Note that on the client side: again, since the idea of gRPC is to be transparently interoperable between languages/runtimes/frameworks, it shouldn't matter whether the client uses the Microsoft or Google transport. Historically there have been some minor differences, but these are a: pretty niche, and b: get fixed when found.
I usually do something like this
1: I create an interface for the service to test the DI system and or to be able to mock it. I do this as registering the gRPC service with the framework kinde-does-that as well as it's created similar to a controller
Then I write my Test like so:
[TestMethod]
public async Task Call_Grpc_Method_Test()
{
var grpcService = _service.GetRequiredService<IMyService>();
var request = new MyRequest {When=DateTime.Now.AddDays(30)};
var context = TestServerCallContext.Create(
method: nameof(IMyService.WinningLotteryNumbers)
, host: "localhost"
, deadline: DateTime.Now.AddMinutes(30)
, requestHeaders: new Metadata()
, cancellationToken: CancellationToken.None
, peer: "10.0.0.25:5001"
, authContext: null
, contextPropagationToken: null
, writeHeadersFunc: (metadata) => Task.CompletedTask
, writeOptionsGetter: () => new WriteOptions()
, writeOptionsSetter: (writeOptions) => { }
) ;
var answer= await grpcService.WinningLotteryNumbers(request, context);
Assert.IsNotNull(answer);
}
IMyService is the gRPC service I want to test and I just create an IServiceProvider that can build one for me via the actual implementations making it an integration test or via mocked objects making it a unit test.
The TestServerCallContext class is located in the NuGet package Grpc.Core.Testing, you would need to add that to your test project.
as to the constructor, well you can use hard coded sample data as I demonstrated or go fancy and add meta data for headers and authcontex as well as the stuff when you need it...
As you can see, not that hard to do once you get started ;-)
I have also raised an issue in the github pages for Edge, linked here
https://github.com/tjanczuk/edge/issues/579
I am trying to utilize Edge in my .NET application to run a quick node program to do some minor video processing.
I have verified that the javascript works - tested it independently running 'node test.js'. And I have verified that I am calling and using the Edge.func method properly by creating a small C# console app and testing to see if, when I run it in CMD (testApp.exe), the video processing works through node using Edge (it does).
The problem is that when I try to run the async method shown below through my POST web service using Edge I get the first log - 'In Edge Task' - but I never get the log at the bottom - 'in async call' - and client side I get a network error saying failed net::ERR_CONNECTION_RESET.
public static async Task Start()
{
LogManager.Instance.WriteLog("In Edge Task");
var func = Edge.Func(#"
var ffmpeg = require('fluent-ffmpeg');
return function (data, callback) {
var proc2 = ffmpeg('testFile-0.webm')
.input('testFile-1.webm')
.on('error', function(err) {
callback(null, 'ERRORRRR');
})
.on('end', function() {
callback(null, '');
})
.mergeToFile('merged-fromNET.mp4', 'tempDir');
}
");
LogManager.Instance.WriteLog("in async call");
await func(null);
}
This async task Start() method works properly if I call it from my test console app...
I have verified my post service is set up correctly because without executing this method using Start.Wait(), commenting it out, the service executes properly. I have installed the necessary node modules and the used video files and necessary dlls in the proper directories so I am sure that is not the issue.
Please help, thank you for your time.
So I figured out the answer to my question with the help of this question -
Starting a process with credentials from a Windows Service
It seems that a web service is executed with "Network Service" permissions and upon checking windows event viewer I was getting an access violation - meaning I needed to execute this chunk of code as a user with proper permissions. So I followed the logic provided in the question I linked to in order to create a process that would execute a simple exe I set up to execute the chunk of code I posted. I had to be careful to give my user proper permissions to access the folder with the exe and that was pretty much it.
With this technique, it seems easy to set up a web service that executes node.js logic with Edge https://github.com/tjanczuk/edge - Thanks tjanczuk
Situation :
To run integration tests on our ASP.NET MVC application, we chose Selenium's Web Driver.
Problem :
When running the tests from VS2015 using Internet Explorer Driver, the console displays an error message (see screenshot below).
Simultaneously, the browser opens and closes. The console freezes. Then, Visual Studio displays a StackOverflow exception message :
Diagnostic :
The test crashes as soon as the driver attempts a navigate action in the app.
[Test]
public void PerformNavigation()
{
Driver.Navigate().GoToUrl(GetAbsoluteUrl("/")); // <-- The test crashes here
}
However an external url works.
[Test]
public void PerformNavigation()
{
Driver.Navigate().GoToUrl("http://google.com"); // <-- This works
}
It seems that the web driver is redirected forever until a stackoverflow exception occurs (HTTP 302).
In debug mode, I can not find the main project's assembly (the one we are testing) in the modules window. It seems that the test project has some trouble loading this specific assembly : all other assemblies are here. I did not find any reason why an assembly couldn't be loaded.
Question :
I could not find any help on Google or SO. Our problem is very specific and may be a combination of issues.
So how can I make these integration tests work ?
Or at least : how can I perform a more precise diagnostic on this issue ?
UPDATE :
I eventually found out that the annotations before my controller methods were interfering with my tests. We use these annotations to check the user rights (here the user can read or update missions) :
[AuthorizedFunctionalities(Functionalities = "Mission_R;Mission_CUD")]
However I find it strange that these tests can not work with such annotations. They work well in debug mode but not through web drivers.
I'll try to investigate further.
You could try to load the assembly (.dll) dynamically, staight in the C# code, at the beginning of the tests.
To do so, you can use the following line of code :
Assembly.LoadFile($"{AppDomain.CurrentDomain.BaseDirectory}\\YourDLL.dll");
I eventually found out that the annotations before my controller methods were interfering with my tests. We use these annotations to check the user rights before the controller's methods:
[AuthorizedFunctionalities(Functionalities = "MyFunctionalities")]
By removing these anotations, the tests work. I still need to know why the web driver doesn't like these.
I'm trying to test my WCF Service Endpoints using IntelliTest I've created the IntelliTest units in a test project, but I need to specify the Server address and port in order for the test to remotely even to work.
This is one of the PexMethods
public ICredentials CredentialsTest()
{
ICredentials result = Service.Credentials();
return result;
// TODO: add assertions to method ServiceTest.CredentialsTest()
}
I've added
Service.ServiceEndPointAddress = "net.tcp://localhost:51010/WCFService";
but when I run the test I get an InvalidProgramException.
What I would like to do is assign the ServiceEndPointAddress once as it is a static property in Service. Anybody that can give some guidance?
There are a couple of issues here:
Getting an InvalidProgramException indicates that IntelliTest has instrumented your code in such a manner as to cause the underlying CLR to raise the exception. That would be a bug in IntelliTest. I request you to file this using the Send a Smile in Visual Studio.
You should not use IntelliTest to directly explore your WCF code. Instead, you should isolate the WCF related external dependencies using mocks (much as you would do if you were writing unit tests by hand), and then run IntelliTest to explore the resultant code. For mocking you can consider using Fakes.
I need to change my unit test from local to remote tests and so far I thought that all I had to do is change UrlToTest to point to another server... But VS keeps on insisting to create a Development Web Server instead of using the one that is already running.
So after reading some docs my question actually is do I have install Test Controller and Test Agent on both remote and local computer or what? What if the WebService is on Linux...
Note that I don't want to debug the application that I'm testing. I simply want tests to be executed for a WebService that is already running, that is deployed.
I probably should mention that all my tests consists of WebService calls and some checks like this:
[TestMethod()]
[HostType("ASP.NET")]
[AspNetDevelopmentServerHost("MainProjectName", "/")]
[UrlToTest("http://servername:port/websitename/TestingOnlyWebForm.aspx")]
public void LoginEmptyDataTest()
{
IUserService userService = CreateIUserService();
string email = "";
string password = "";
ReturnMessage<User> actual;
actual = userService.Login(email, password);
Assert.AreNotEqual(true, actual.Status);
Assert.AreNotEqual("db_error", actual.Info);
}
But I have also more complicated tests in which I change some data and send it to another WebService and so on.
Note that UrlToTest previously was pointing to localhost at which point it works but starts a developer server which is not what I want.
What you are trying to is not possible. All that generated unit test is trying to do is to run the test locally on the machine either using the development server by specifying AspNetDevelopmentServerHost or by using local IIS, when AspNetDevelopmentServerHost is not present.
If you want to test remote services right click your unit test project and add a service reference. Point to your service give it a namespace, say Services, and generate the proxies. Once you have the proxies generated just instantiate them and call the methods. Also remove all the unneeded attributes from your test. Your test should roughly look like this:
[TestMethod]
public void LoginEmptyDataTest()
{
using (var userServiceClient = new Services.UserServiceClient(
"BasicHttpBinding_IUserService",
"http://someremotehost/userservice.svc"))
{
var result = userServiceClient.Login("user", "password");
// asserts go here
}
}
This may solve your immediate problem however you should re-think what you are doing as #eglasius said. what happens if the code you call changes state internally? Next test might fail because of that so you need clean-up strategies otherwise your tests will be very brittle and you'll end up ignoring them.
Update: passing an address at run-time. Change the first parameter to whatever enpoint configuration name you have in your config file.
I'll take a stab in the dark at this one because I did something similar recently.
In my case my test project referenced the service project to provide visibility of the service and data contracts the Web Service implements and consumes.
To resolve this - though it can be ignored - move the contracts to a new project. Then have the service and test projects reference the new project, and remove the test projects' reference to the service.
Hope that makes sense!
Once the reference is removed, VS will no longer feel the need to start up your service when you run your tests.
You can disable the startup of the Service Host in the Project settings of your WCF Service Project. Right Click - WCF Options - Uncheck "Start WCF Service Host when debugging another project in the same solution".
You really have to consider the nature of what you're trying to achieve here.
It's hard to tell exactly what you're hitting of the code. I have the impression, you have is a website that calls a web service. You're testing the client code in that context, instead of just testing the service.
If that's the case, remove the attributes and point the url to the correct service like UrbaEsc guided you to. If you don't remove the attributes, you're running the calling code in the context of the site.
Even if the above is not the scenario, and based on what you replied to UrbanEsc in the comments, you'd then be testing an external call to the webservice initiated from the same site process.
You said:
"Found it, but VS still starts something on localhost and then trys to reach external server... Seems like VS is just not designed for real remote testing of webservices"
Read the above. I'd say you need to better understand what you're enabling. You can certainly test remote web services, like you can do pretty much anything you can code. You do that from client code that knows nothing different that what any other external client of the service would know. Support doesn't stop there, as you can do load testing of the service.
Note that what you're doing aren't unit tests, these are integration tests. Or depending on the scope of your system, full system tests.