Unit testing ExceptionFilterAttribute - unit-testing

I'm trying to unit test my exception filter code. I can validate the exception, but I can't seem to find the exception message to validate in the unit test. Here is my code...
public class ExceptionHandlingAttribute : ExceptionFilterAttribute
{
public override void OnException(HttpActionExecutedContext context)
{
if (context.Exception is TimeoutException)
{
context.Response = context.Request.CreateErrorResponse(HttpStatusCode.RequestTimeout, context.Exception.Message);
return;
}
if (context.Exception is UnauthorizedAccessException)
{
context.Response = context.Request.CreateErrorResponse(HttpStatusCode.Unauthorized, context.Exception.Message);
return;
}
context.Response = context.Request.CreateErrorResponse(HttpStatusCode.InternalServerError, "Unable to process your request.");
}
}
Unit Test Code
[Theory, MemberData("ExceptionData")]
public void OnExceptionTests(Exception ex, HttpStatusCode statusCode)
{
var request = new HttpRequestMessage();
var actionContext = InitializeActionContext(request);
var httpActionExectuedContext = new HttpActionExecutedContext(actionContext, ex);
var exceptionHandlingAttribute = new ExceptionHandlingAttribute();
exceptionHandlingAttribute.OnException(httpActionExectuedContext);
Assert.Equal(actionContext.Response.StatusCode, statusCode);
Assert.Equal(actionContext.Response.ReasonPhrase, ex.Message);
}
public static IEnumerable<object[]> ExceptionData
{
get
{
return new[]
{
new object[] { new TimeoutException("My timeout message."), HttpStatusCode.RequestTimeout }
};
}
}
My problem is : Assert.Equal(actionContext.Response.ReasonPhrase, ex.Message);
When I try to look at it in the watch window, I can't seem to find "My Timeout message" in the response.
UPDATE:
actionContext.Response.ReasonPhrase = "Request Timeout"
ex.Message = "My timeout message"

The message portion of the CreateErrorResponse isn't a property, you have to read the content to get the value. Here's what I did...
var responseContent = await actionContext.Response.Content.ReadAsStringAsync();
After reading, responseContent now had:
{ "message" : "My timeout message." }

Related

Xamarin Async and Await: UI thread is getting blocked

I have this architecture in my project and sometimes UI thread is getting blocked, can someone please explain what is happening with the below code. Thanks
I am making a service call asyncronously from xamarin.forms viewmodel
Following is the flow
View--->ViewModel---ClassA--->ClassB--Make a service call from here
Code
Scenario 1
public partial class HomePage : ContentPage
{
private HomeVM model;
public HomePage()
{
InitializeComponent();
model = new HomeVM();
model.MainText = ReturnBool().Result;
this.BindingContext = model;
}
public async Task<string> ReturnBool()
{
IsBusy = true;
var r = await new WS().ReturnBool();
IsBusy = false;---------------------------------------Not hitting the breakpoint here
return r;
}
}
public interface IWS
{
Task<string> ReturnBool();
}
public class WS : IWS
{
public Task<string> ReturnBool()
{
return ServiceOperations.ReturnBool();
}
}
internal class ServiceOperations
{
public async static Task<string> ReturnBool()
{
var uri = new Uri(string.Format("http://testmyapi.azurewebsites.net/", string.Empty));
try
{
HttpClient client = new HttpClient();
client.BaseAddress = uri;
HttpResponseMessage response = null;
response = await client.GetAsync("/api/Values/Get");
if (response.IsSuccessStatusCode)
{
var content = await response.Content.ReadAsStringAsync();
string str = JsonConvert.DeserializeObject<string>(content);
return str;
}
else {
return null;
}
}
catch (Exception)
{
return null;
}
}
}
Scenario 2
public partial class HomePage : ContentPage
{
private HomeVM model;
public HomePage()
{
InitializeComponent();
model = new HomeVM();
this.BindingContext = model;
}
}
public class HomeVM : BaseVM
{
private string mainText;
public string MainText
{
get { return mainText; }
set
{
mainText = value;
RaisePropertyChanged("MainText");
}
}
public HomeVM()
{
MainText = ReturnBool().Result;
}
public async Task<string> ReturnBool()
{
IsBusy = true;
var r = await new WS().ReturnBool();
IsBusy = false;---------------------------------------Not hitting the breakpoint here
return r;
}
}
public interface IWS
{
Task<string> ReturnBool();
}
public class WS : IWS
{
public Task<string> ReturnBool()
{
return ServiceOperations.ReturnBool();
}
}
internal class ServiceOperations
{
public async static Task<string> ReturnBool()
{
var uri = new Uri(string.Format("http://testmyapi.azurewebsites.net/", string.Empty));
try
{
HttpClient client = new HttpClient();
client.BaseAddress = uri;
HttpResponseMessage response = null;
response = await client.GetAsync("/api/Values/Get");
if (response.IsSuccessStatusCode)
{
var content = await response.Content.ReadAsStringAsync();
string str = JsonConvert.DeserializeObject<string>(content);
return str;
}
else {
return null;
}
}
catch (Exception)
{
return null;
}
}
}
You are using ReturnBool().Result in the constructor. The return call will block your UI thread. Move that code to the controller action methods without using ".Result" part. Ensure that the methods are async and always return a Task.

Post JSON Object using httpClient windows Phone 8.1

I'm trying to post a json Object to a web api project from a windows phone app but I'm still getting 404 error. For the post method, I'm using that code:
Mail mailToCheck = new Mail();
try
{
mailToCheck.MailProfil = TxtBox_mail.Text.ToString();
string json = JsonConvert.SerializeObject(mailToCheck);
var httpClient = new System.Net.Http.HttpClient(new HttpClientHandler());
System.Net.Http.HttpResponseMessage response = await httpClient.PostAsync(new Uri("http://uri/api/Profil/CheckMail"), new StringContent(json));
var responseString = await response.Content.ReadAsStringAsync();
}
catch (Exception ex)
{
MessageBox.Show(ex.HResult.ToString());
}
The method CheckMail on my conctroller:
[HttpPost]
[Route("api/Profil/CheckMail")]
public IHttpActionResult CheckMail([FromBody]Mail MailProfil)
{
if (MailProfil.MailProfil != null)
{
try
{
bool exists = Librairie.Profils.mailExists(MailProfil.MailProfil);
return Ok(exists);
}
catch(Exception ex)
{
return InternalServerError(ex);
}
}
else
{
return BadRequest();
}
}
The Mail object is exactly the same in the app as in the web api project. Does someone can tell me what I'm doing wrong here ?
Check some samples of HttpClient.PostAsync() here: https://monkeyweekend.wordpress.com/2014/10/23/how-to-send-text-json-or-files-using-httpclient-postasync/

Change Activity into Fragment

I am quite new at Android.
So I am a bit confused of working with fragments.
I have found a very great tutorial.
So I have working code. But it is the layout oft a normal activity.
Then I tried to include it into a navigation drawer.
So the list view with data will only be shown when the menu item has been selected.
On the fragment View there is a never ending loading Dialog.
While debugging I have figured out that the code loads still the data and inserts it into feedItems.
So feedItems is filled correctly.
Now after listAdapter.notifyDataSetChanged() there happens nothing.
So here that is my code:
public class FragmentNews extends ListFragment {
private static final String TAG = FragmentNews.class.getSimpleName();
private ListView listView;
private FeedListAdapter listAdapter;
private List<FeedItem> feedItems;
private String URL_FEED = "http://address.com";
public FragmentNews(){}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onActivityCreated(savedInstanceState);
loadDataForNews();
}
private void loadDataForNews(){
listView = this.getListView();
feedItems = new ArrayList<FeedItem>();
listAdapter = new FeedListAdapter(getActivity(), feedItems);
listView.setAdapter(listAdapter);
// We first check for cached request
Cache cache = AppController.getInstance().getRequestQueue().getCache();
Entry entry = cache.get(URL_FEED);
if (entry != null) {
// fetch the data from cache
try {
String data = new String(entry.data, "UTF-8");
try {
parseJsonFeed(new JSONObject(data));
} catch (JSONException e) {
e.printStackTrace();
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
} else {
// making fresh volley request and getting json
JsonObjectRequest jsonReq = new JsonObjectRequest(Method.GET,
URL_FEED, null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
VolleyLog.d(TAG, "Response: " + response.toString());
if (response != null) {
parseJsonFeed(response);
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d(TAG, "Error: " + error.getMessage());
}
});
// Adding request to volley request queue
AppController.getInstance().addToRequestQueue(jsonReq);
}
}
// List View Feed
private void parseJsonFeed(JSONObject response) {
try {
JSONArray feedArray = response.getJSONArray("feed");
for (int i = 0; i < feedArray.length(); i++) {
JSONObject feedObj = (JSONObject) feedArray.get(i);
FeedItem item = new FeedItem();
item.setId(feedObj.getInt("id"));
item.setName(feedObj.getString("name"));
// Image might be null sometimes
String image = feedObj.isNull("image") ? null : feedObj
.getString("image");
item.setImge(image);
item.setStatus(feedObj.getString("status"));
item.setProfilePic(feedObj.getString("profilePic"));
item.setTimeStamp(feedObj.getString("timeStamp"));
// url might be null sometimes
String feedUrl = feedObj.isNull("url") ? null : feedObj
.getString("url");
item.setUrl(feedUrl);
feedItems.add(item);
}
// notify data changes to list adapater
listAdapter.notifyDataSetChanged();
} catch (JSONException e) {
e.printStackTrace();
}
}
}
Can the problem be that the inflater of listAdapter is null?
Thanks for help!
Sometimes listAdapter.notifyDataSetChanged() does not work properly.
Try removing
listAdapter = new FeedListAdapter(getActivity(), feedItems);
listView.setAdapter(listAdapter);
from loadDataForNews() and adding in
place of listAdapter.notifyDataSetChanged();

The system crashes and can not display the error message

assume the code is correct and webservice timeout occurs.
The problem :
The system crashes and can not display the error message.
How to display error message? So I can provide an alternative to user when there is an error?
1)
I add this Class in the project :
public class MyClass
{
public static async Task LogInSuccess()
{
try
{
-- calling a web service here
}
catch (System.Exception _ex)
{
_strErrorMsg = _ex.InnerException.Message;
throw new Exception("LogInSuccess() " + _strErrorMsg);
}
}
}
--- In the MainPage,
2)
private async void SetUp ()
{
-- code for doing setUp task--
CallWebSvc();
}
3)
private void CallWebSvc()
{
bool ShowError = false;
System.Exception MyException = new Exception();
try
{
-- calling a web service thru the MyClass
System.Threading.Tasks.Task _blnLogInSuccess = MyClass.LogInSuccess();
await _blnLogInSuccess;
if (_blnLogInSuccess.IsCompleted)
{
g_blnLoginStatus = _blnLogInSuccess.Result;
}
}
catch (System.Exception _ex)
{
ShowError = true;
MyException = ex;
}
if (ShowError)
{
var MyMessageBox = new Windows.UI.Popups.MessageDialog("Remote Login Error:" + MyException.Message, "Start Login" );
await MyMessageBox.ShowAsync();
}
}
I assume your CallWebSvc method is async void (as, without async you cannot perform an await) If this is the case, you need to know async void doesn't do the same treatament to exceptions as async task. they aren't catched correctly. If you change your CallWebSvc from async void to async Task, you are going to receive the exception correctly.

uploading file from backberry to web service = JVM error 104 Uncaught NullPointerException?

I am developing a small blackberry project.
Here are the step that it is supposed to be:
User clicks Speak! button. The application record speech voice. [No Problem]
When user finishes speaking, click Stop! button. Once the stop button is clicked, the speech voice will be saved on BB as an AMR file. Then, the file will be sent to web service via ksoap2. Web service will return response as a string of file name. The problem is web service return nothing and there is an error occur: JVM error 104: Uncaught NullPointerException I wonder if I placed the code on the right place, or I did something wrong with ksoap2??
here is the code for web service
namespace VoiceServer
{
/// <summary>
/// Converting AMR to WAV
/// </summary>
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
public class Service1 : System.Web.Services.WebService
{
public string UploadFile(String receivedByte, String location, String fileName)
{
String filepath = fileName;
/*don't worry about receivedByte and location, I will work on them after the problem is solved :) */
return "Success"+filepath;
}
private void InitializeComponent()
{
}
}
}
Below is the code running on Eclipse, I'm not sure if I placed the code for sending file to web service on the right place.
public class MyAudio extends MainScreen {
private ButtonField _startRecordingButton;
private ButtonField _stopRecordingButton;
private HorizontalFieldManager _fieldManagerButtons;
private VoiceNotesRecorderThread _voiceRecorder;
private LabelField _myAudioTextField;
private DateField hourMin;
private long _initTime;
public MyAudio() {
_startRecordingButton = new ButtonField("Speak!", ButtonField.CONSUME_CLICK);
_stopRecordingButton = new ButtonField("Stop!", ButtonField.CONSUME_CLICK);
_fieldManagerButtons = new HorizontalFieldManager();
_voiceRecorder = new VoiceNotesRecorderThread(500000,"file:///store/home/user/voicefile.amr",this);
_voiceRecorder.start();
myButtonFieldChangeListener buttonFieldChangeListener = new myButtonFieldChangeListener();
_startRecordingButton.setChangeListener(buttonFieldChangeListener);
_stopRecordingButton.setChangeListener(buttonFieldChangeListener);
_fieldManagerButtons.add(_startRecordingButton);
_fieldManagerButtons.add(_stopRecordingButton);
_myAudioTextField = new LabelField(" Welcome to VoiceSMS!!!" );
add(_fieldManagerButtons);
add(_myAudioTextField);
SimpleDateFormat sdF = new SimpleDateFormat("ss");
hourMin = new DateField("", 0, sdF);
hourMin.setEditable(false);
hourMin.select(false);
_initTime = System.currentTimeMillis();
add(hourMin);
}
public void setAudioTextField(String text) {
_myAudioTextField.setText(text);
}
public void startTime() {
_initTime = System.currentTimeMillis();
hourMin.setDate(0);
}
public void updateTime() {
hourMin.setDate((System.currentTimeMillis()-_initTime));
}
class myButtonFieldChangeListener implements FieldChangeListener{
public void fieldChanged(Field field, int context) {
if(field == _startRecordingButton) {
try {
_voiceRecorder.startRecording();
} catch (IOException e) {
e.printStackTrace();
}
}else if(field == _stopRecordingButton) {
_voiceRecorder.stopRecording();
//----------Send AMR to Web Service-------------//
Object response = null;
String URL = "http://http://localhost:portnumber/Service1.asmx";
String method = "UploadFile";
String NameSpace = "http://tempuri.org/";
FileConnection fc = null;
byte [] ary = null;
try
{
fc = (FileConnection)Connector.open("file:///store/home/user/voicefile.amr",Connector.READ_WRITE);
int size = (int) fc.fileSize();
//String a = Integer.toString(size);
//Dialog.alert(a);
ary = new byte[size];
fc.openDataInputStream().read(ary);
fc.close();
}
catch (IOException e1)
{
e1.printStackTrace();
}
SoapObject client = new SoapObject(NameSpace,method);
client.addProperty("receivedByte",new SoapPrimitive(SoapEnvelope.ENC,"base64",Base64.encode(ary)));
client.addProperty("location","Test/");
client.addProperty("fileName","file:///store/home/user/voicefile.amr");
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.bodyOut = client;
HttpTransport http = new HttpTransport(URL);
try
{
http.call(method,envelope);
}
catch(InterruptedIOException io)
{
io.printStackTrace();
}
catch (IOException e)
{
System.err.println(e);
}
catch (XmlPullParserException e)
{
System.err.println(e);
}
catch(OutOfMemoryError e)
{
System.out.println(e.getMessage());
}
catch(Exception e)
{
e.printStackTrace();
}
try
{
response = envelope.getResponse();
Dialog.alert(response.toString());
}
catch (SoapFault e)
{
System.err.println(e);
System.out.println("Soap Fault");
}
catch(NullPointerException ne)
{
System.err.println(ne);
}
Dialog.alert(response.toString());
//Dialog.alert("Send Success");
//----------End of Upload-to-Web-Service--------//
}
}
}
}
I don't know if the file is not sent to web service, or web service has got the file and produce no response??? I am a real newbie for BB programming. Please let me know if I did anything wrong.
Thanks in advance!!!
There is a typo in your URL variable value.
"http://" typed twice
String URL = "http://http://localhost:portnumber/Service1.asmx";
Hooray!!! Problem Solved!
just changed URL as Rafael suggested and added [WebMethod] above "public string UploadFile" in the web service code