I'm new to testing and test automation and I'm trying to test a REST API for performance. For this my primary preference is Visual Studio but I'd like to hear about other options too. I want to capture the json response from a REST call, extract some parameters from the JSON response I got and pass them to the next REST call. It's like automatic parameter detection. I did a search online but could only find something like this https://msdn.microsoft.com/library/dn250793.aspx but no where they really talk about testing REST service with Visual Studio. Any pointers will be of great help. Thank you.!
You can easily talk to a JSON REST Web API service from C# code. You'd need the service running then you can write tests which talk to the API service and give you timings or parse the response and call the next API method, etc.
Here's a simple example
public async Task<YourResponseDTO> GetResponseDTO()
{
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("localhost/your-web-api/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = await client.GetAsync("your-first-endpoint");
if (!response.IsSuccessStatusCode)
{
return null;
}
var mediaType = response.Content.Headers.ContentType.MediaType;
if (mediaType != "application/json")
{
return null;
}
var responseObject = await response.Content.ReadAsAsync<YourResponseDTO>();
return responseObject;
}
}
You simply write the class YourResponseDTO to match whatever fields come out of JSON and this code will automatically populate the fields.
Related
Getting really irritated with this. The playground gives only python and node, trying to use this in C# and I keep getting errors. Here is how I have it setup.
First in the Program / Startup file, I am setting it up like so: (URL: https://api.openai.com/)
services.AddHttpClient("ChatGptAPI", client =>
{
client.DefaultRequestHeaders.Clear();
client.BaseAddress = aiOptions.Url;
client.DefaultRequestHeaders.Add("Authorization", "Bearer " + aiOptions.Bearer);
});
Then in my method, I am calling this:
var client = _httpFactory.CreateClient("ChatGptAPI");
var payload = new
{
prompt = $"Create a first person story\n\n{storyText}",
temperature = "0.5",
max_tokens = "1500",
model = "text-davinci-003"
};
var content = new StringContent(JsonSerializer.Serialize(payload), Encoding.UTF8, "application/json");
var response = await client.PostAsync("v1/completions", content);
Console.WriteLine("ChatGptAPI result:");
Console.WriteLine(response.RequestMessage);
I at first I kept getting Bad Request errors, but once I tried other URLs for the request, it appears to go through, but the response is blank.
For the life of me, I cannot find any samples out there that has C# calling these services.
Any help would be great.
I have tried multiple URLs, I've tried running this in Playground and view code and I've searched for other samples, but this keeps failing or returning nothing. Also tried using the OpenAI Nuget package, that was a waste of time.
If you are actually managing to reach the completions endpoint and you have a valid key then you are just reading the wrong object back.
After you get your response you should read it, something like:
var gptResponse = await response.Content.ReadAsStringAsync();
you can then parse or better deserialize the API response
I'm making an http request post to an external api. I am constructing a json object to add to the request body. How can I check if the added body/content is correct before it is sent.
public async void TestAuthentication()
{
var client = new HttpClient();
var request = new HttpRequestMessage()
{
RequestUri = new Uri("http://test"),
Method = HttpMethod.Post
};
var jsonObj = new
{
data = "eneAZDnJP/5B6r/X6RyAlP3J",
};
request.Content = new StringContent(JsonConvert.SerializeObject(jsonObj), Encoding.UTF8, "application/json");
var response = await client.SendAsync(request);
}
If you are not sure whether the serialization works as intended, you could give it a shot in LINQpad or dotnetfiddle.net. See my example that returns the JSON on the console. These tools are great for quick prototyping a method or a snippet, if you are not sure if a piece of code works as intended.
You could also check in Wireshark, but that could be a bit of an overkill and works best if your connection if not encrypted (no HTTPS).
I personally tend to test code that calls some API the following way:
Make the called URL parameterizable (via the classes constructor)
If there is any variable data this data should be passed as the methods parameter(s)
For your test start an HTTP server from your test fixture (read on testing with xUnit or NUnit if you don't know what this means)
I use PeanutButter.SimpleHTTPServer for that
Pass the local IP to the class that accesses the API
Check whether the HTTP server received the expected data
Whether or not this kind of code shall be tested (this way) may be debatable, but I found this way to work kind of good. I used to abstract the HttpClient class away, but IMHO I would not recommend this anymore, because if the class accesses the API (and does not do anything else, which is important), the HTTP access is the crucial part that shall be tested and not mocked.
I'm unsure how to add the Session Request to the API call as per the Food Hygiene Instructions. I've copied the relevant code and hope I am close, but unsure where to put this one part.
Reference: https://api.ratings.food.gov.uk/help
Need to add into the API call: Session.Request.Headers.Add("x-api-version", 2);
Partial Code:
readonly string Baseurl = "https://api.ratings.food.gov.uk";
public async Task<ActionResult> Index()
{
List<Authorities> AuthInfo = new List<Authorities>();
using var client = new HttpClient
{
//Passing service base url
BaseAddress = new Uri(Baseurl)
};
client.DefaultRequestHeaders.Clear();
//Define request data format
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
***//Session.Request.Headers.Add("x-api-version", 2);***
//Sending request to find web api REST service resource GETRegions using HttpClient
HttpResponseMessage Res = await client.GetAsync("Authorities/basic");
The documentation you're referring to is misleading/incorrect. When you talk about Session (at least in the .NET world) you talk about the server-side. You're obviously a client of the API, rather than a developer of it, so they asking you to put stuff in the Session is incorrect.
You're a client, passing headers in your requests, so it's just:
client.DefaultRequestHeaders.Add("x-api-version", "2");
Side note, you may want to reuse that HttpClient instance if you are going to make that call often.
Side note 2: you may want to ask them to fix the docs :)
how can you send both the access_token and id_token to your api using System.Net.Http? when i was testing my api with postman it seemed to send both tokens and returned the individual user information I needed (a list of products the user is selling). I am unsure how I can do this in my Xamarin app and have being stuck on this for quite some time. I am able to send the access_token as shown below but anything I have tried when sending both tokens has returned a 404 not found. (unauthorized is corrected to a 401 so the access_token is still working)
public async Task<string> GetResponseJsonString(string url)
{
string responseJsonString = null;
var access_token = CrossSecureStorage.Current.GetValue("access_token");
using (var httpClient = new HttpClient())
{
httpClient.DefaultRequestHeaders.Clear();
httpClient.DefaultRequestHeaders.Add("Authorization", "Bearer " + access_token);
HttpResponseMessage response = httpClient.GetAsync(url).Result;
responseJsonString = await response.Content.ReadAsStringAsync();
}
return responseJsonString;
}
Note: I am aware the id_token should contain the user information and it should be decoded rather than sending requests for user information. I looked at this and have been unable to find a library that works in a xamarin PCL. I looked at JosePCL.Jwt but was unable to get it to work. I figure since any time I need user information it is returning information from my database that it made sense to send both tokens with the request and let my api get the user information.
This is entirely dependent on the API you're calling. I've never seen an API that needs something more than the access_token it's provided back to you. It's possible you have the nomenclature incorrect here.
Do you mean "access key & secret"? Or are you certain you have an access_token?
In the former case, normally API's will expect things as followed:
Append the key & secret together separated by a ":"
Base64 Encode
Set the Authorization Bearer|Basic header with the result
It's also worth asking if you've tried passing in the id_token as the Authorization header?
It's also also worth asking if you can provide us with a screen capture of the successful response from postman (make sure you obfuscate the sensitive data).
It's also also also worth pointing out an optimization tweak for your code. Since you're using async, it seems you probably are somewhat concerned about performance. Have a look at this article, discussing the disposability of HttpClient. As a better alternative, use HttpRequestMessage as follows:
public async Task<string> GetResponseJsonString(string url)
{
string responseJsonString = null;
var req = new HttpRequestMessage(HttpMethod.Get, "/your/api/url");
req.Headers.Authorization = new AuthenticationHeaderValue("Bearer", access_token);
using (var resp = await client.SendAsync(req))
using (var s = await resp.Content.ReadAsStreamAsync())
using (var sr = new StreamReader(s))
{
if (resp.IsSuccessStatusCode)
{
responseJsonString = await sr.ReadToEndAsync();
}
else
{
string errorMessage = await sr.ReadToEndAsync();
int statusCode = (int)resp.StatusCode;
//log your error
}
}
return responseJsonString;
}
Where client is a reference to a statically shared instance of HttpClient. My preferred way to do all this, is to wrap my API calls, usually one-file-per-service. I inject this service as a singleton, which will broker it's own static instance of HttpClient. This setup is even more straightforward if you're using .NET Core.
As the question says, is it possible? I need my code in server side to call a third-party REST API to get some data.
As mentioned by #ramiramilu you can use HttpClient class to achieve the same.
var client = new HttpClient();
client.BaseAddress = new Uri("http://mybaseaddress/");
HttpResponseMessage response = await client.GetAsync("someEndpoint");
if (response.IsSuccessStatusCode)
{
var model = await response.Content.ReadAsAsync<MyModel>();
}
Hope it helps!
If you are using .net 4.5 , You can do an ASync request.
This is rather similar in concept to what you're asking for.