I have a simple entity and trying to make fail the save method for my unit test.
The question is, how can I make the save method to fail and return false?
public class Sampple
{
public int Id { get; set; }
public string Name{ get; set; }
}
public bool Save()
{
return (_applicationDbContext.SaveChanges() >= 0);
}
Like #Yohannis said, dont waste your time testing EF itself.
If you are looking to test what might happen if a dbcontext.SaveChanges() failed, whether that be for an incorrectly parsed property or whatever.
try something like this:
`try {
//_applicationDbContext.SaveChanges()
throw new Exception();
// Remember to replace _applicationDbContext.SaveChanges() with
//'new Exception' when you are outside of the development db
return(true); //whilst exception active, here is not hit
}
catch (Exception e) {
//Error handling here
return(false);
}`
A try catch will try to complete a process, if it cant, the catch will 'catch' the thrown exception. In our case we have purposely thrown anew Exception so that we can see exactly what would happen if _applicationDbContext.SaveChanges() did fail. I have included a very basic Exception but there are many types that you can use and tailor to exactly what kind of error you might want to test for.
I have included a link with some relatively simple examples for your consideration.
https://www.codeproject.com/Articles/850062/Exception-handling-in-ASP-NET-MVC-methods-explaine
Related
What is a good way to bubble up a DbUpdateConcurrencyException to the view from the grain?
I'm currently working on an Orlean's prototype that has a custom state that I'm using Entity Framework Core to communicate with the DB and using the optimistic concurrency patterns built into EF Core to manage the concurrency issues.
Where I'm having an issue is that I want to bubble up my Exception from the grain to the view and am not receiving it on the view end.
I'm trying to accomplish this because I want to deal with some of the concurrency issues that are more pressing on the view so that the user can decide or at least be alerted to the issue.
I brought this up on the Orlean's Gitter, but didn't get many ideas from it.
Example of my code for updating:
public Task UpdateUser(User user)
{
//Reason for second try/catch is to bubble the error to controller
try
{
userState = new User
{
Username = this.GetPrimaryKeyString(),
accountType = user.accountType,
FName = user.FName,
LName = user.LName,
RowVersion = user.RowVersion,
CreatedDate = user.CreatedDate
};
UpdateState();
}
catch (DbUpdateConcurrencyException ex)
{
throw ex;
}
return Task.CompletedTask;
}
public Task UpdateState()
{
using (var context = new OrleansContext())
{
context.users.Update(userState);
try
{
context.SaveChanges();
}
catch ( DbUpdateConcurrencyException ex)
{
var entry = ex.Entries.Single();
var clientValues = (User)entry.Entity;
var databaseEntry = entry.GetDatabaseValues();
//Make sure the row wasn't deleted
if(databaseEntry != null)
{
var databaseValues = (User)databaseEntry.ToObject();
if(clientValues.accountType != databaseValues.accountType)
{
//Bubble up the exception to controller for proper handling
throw ex;
}
//Update Row Version to allow update
userState.RowVersion = databaseValues.RowVersion;
context.SaveChanges();
}
}
}
return Task.CompletedTask;
}
I'm open to any suggestions on this as long as it allows the user to be alerted to the Exception and can view their data and the current DB values.
There is a chance that the exception is not being serialized or deserialized correctly. The primary reasons for this could be:
The Exception class does not correctly implement the ISerializable pattern.
The assembly which contains the Exception class is not present on the client, so the client does not understand how to create the Exception type.
In this case, I would lean towards the second reason, because most (but not all!) Exception classes do correctly implement the ISerializable pattern.
In either case, you can catch your exception and turn it into a generic exception.
You could create a helper method to do this using the LogFormatter.PrintException(Exception) method from Orleans to format the exception as a string.
public static void ThrowPlainException(Exception e) =>
throw new Exception(Orleans.Runtime.LogFormatter.PrintException(e));
The solution I came to was to create a custom exception class that serializable add the database values object to it and bubble that up to the views.
[Serializable]
public class UpdateException : Exception
{
public object databaseValues { get; set; }
public UpdateException(object databaseValues)
{
this.databaseValues = databaseValues;
}
public UpdateException(string message, object databaseValues) :base(message)
{
this.databaseValues = databaseValues;
}
}
I'm using Newtonsoft Json.NET library version 9 with ASP.NET WebApi2 and sending the following JSON to my method
{
id:1,
items:[{
foo:1.23
}]
}
on the server, items collection has type Bar[], where Bar is
public class Bar
{
public int Foo { get; set; }
}
unfortunately, instead of throwing an exception when trying to convert 1.23 to int as I would expect, my method gets invoked with Items collection being an empty array.
Apparently, the problem is similar to this issue, https://github.com/JamesNK/Newtonsoft.Json/issues/654 , and should not occur in versions higher than 6, but we are, as mentioned, on version 9 (current latest).
Is there any kind of configuration I can make to prevent such silent behavior? I'm in an enterprise environment, and would like to have exceptions thrown instead of data loss.
Update
As short term solution, I've configured exception handling, as follows
GlobalConfiguration.Configuration.Formatters
.JsonFormatter.SerializerSettings.Error += (o, e) =>
{
// this errors bubble through each parent, we only want to log once.
if (e.CurrentObject == e.ErrorContext.OriginalObject)
{
_logger.Error(e.ErrorContext.Error.Message, e.ErrorContext.Error);
}
throw e.ErrorContext.Error;
};
For now, at-least, i'm getting null instead of entire method parameter, which is better. As suggested by Dbc below, it looks like the error did get thrown, but was then simply swallowed during request binding. With the new handler it does not. Continuing research.
It looks like the problem was with with WebApi / MVC, as they do not consider partially invalid model reason enough to stop execution.
We have now added a special attribute to achieve this to our base API controller, as described at https://learn.microsoft.com/en-us/aspnet/web-api/overview/formats-and-model-binding/model-validation-in-aspnet-web-api
public class ValidateModelAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(HttpActionContext actionContext)
{
if (actionContext.ModelState.IsValid == false)
{
actionContext.Response = actionContext.Request.CreateErrorResponse(
HttpStatusCode.BadRequest, actionContext.ModelState);
}
}
}
I am migrating to version 6 of Reactive UI, and am trying to more completely use the tools it provides, namely ThrownExceptions. Nothing happens when I subscribe to the thrown exceptions property. I'm sure I'm missing something just not sure what it is right now.
In my simplified example, there is a button with a command bound it it.
public ReactiveCommand<object> Delete { get; private set; }
public MainWindowViewModel()
{
Delete = ReactiveCommand.Create();
Delete.Subscribe(e => CommandExec());
Delete.ThrownExceptions.Subscribe(ex => HandleException(ex));
}
private object HandleException(Exception ex)
{
MessageBox.Show("Exception Handled");
return null;
}
public IObservable<object> CommandExec()
{
throw new Exception("throwing");
}
My assumption is that I would see an "Exception Handled" MessageBox when the exception was thrown. I'm sure i'm subscribing to something, it's just not clear what it is right now.
ThrownExceptions only applies to the background operation declared with CreateAsyncXYZ:
var someCmd = ReactiveCommand.CreateAsyncObservable(_ =>
Observable.Throw<Unit>(new Exception("Oh Noes!"));
someCmd.ThrownExceptions.Subscribe(ex => Console.WriteLine(ex.Message));
await someCmd.ExecuteAsync();
>>> Oh Noes!
In ReactiveUI, you should never put Interesting™ code inside the Subscribe block - Subscribe is solely to log the result of operations, or to wire up properties to other properties.
My simple wcf returning some data as dto object (MyDataDto). This dto is ofcourse created using MyData object which is created using data returned from repository.
public MyDataDto GetData(string filter)
{
MyData data = repository.GetData(filter);
return new MyDataDto(data);
}
If this data object is null (no data returned from repository) then I'm getting exception (ofcourse).
Question is: Should I decorate my OperationContract method with ObjectNotFoundException and to handle that exception at client side or to add new property at MyDataDto object with property bool IsEmpty and to return empty object?
Since I'm pretty new using wcf service what you consider as better practice or you suggest something else.
We can not use a normal .net exception in order to propagate the error to the client you can use a customized exception through the use of the FaultContract Attribute something like this
[DataContractAttribute]
public class MyDataDtoFault
{
private string report;
public MyDataDtoFault(string message)
{
this.report = message;
}
[DataMemberAttribute]
public string Message
{
get { return this.report; }
set { this.report = value; }
}
}
[OperationContract]
[FaultContract(typeof(MyDataDtoFault))]
public MyDataDto GetData(string filter)
{
MyData data = repository.GetData(filter);
if (data==null)
throw new MyDataDtoFault("No result Was found");
return new MyDataDto(data);
}
or you can use a simple FaultException by default which is serilizable and represents a SOAP fault.
but creating a property IsEmpty it will be correct but the client who would like to consume the service must be aware that this property means no result was found
personally I prefer raising an exception which is more convenient way of doing this
The best practice and recommended way is to NOT throw exceptions if you have found data and then have your program flow the exceptions. This not only produces performance hits and issues but also is just bad flow of logic. Also means difficult to maintain and lengthy code blocks/spaghetti junction.
The best practice is to create a class which has a Success property for example to indicate if the operation was a success (i.e no SQL Errors or any other exceptions) and then return the data in an exposed property in this custom class. If there is no data then really MyData is null and therefore the client side can check to see if it is null (or if collection... make sure the items are 0 in count/length and instantiated as empty). Example...
[DataContract]
public sealed Class MyDataResults
{
public MyDataResults()
{
this.Success = false;
this.FailureInformation = string.Empty;
this.Results = new MyData();
}
[DataMember(IsRequired = true)]
public bool Success {get; set;}
[DataMember(IsRequired = true)]
public MyData Results {get; set;}
[DataMember(IsRequired = true)]
public string FailureInformation {get; set;}
}
you return MyDataResults instead.
this also means you have a nice POCO object to deal with and has more meaning of a contract in that "I guarantee the client will receive this object and not something they don't expect and maybe even produce contract breakage"
So if you have an exception on server side (like FileNotFound for example), set the Success to false, set the FailureInformation to a nice friendly message to return back.
The client would check to see if the operation was a Success and if not, display the FailureInformation.
My practice is to return a fault if the operation cannot do what it was requested to do. However, one then needs to examine what it was that the operation was requested to do:
public MyDto GetEntityById(int id)
This operation has been requested to return the entity with the given ID. If it cannot do that, then I feel it is appropriate to return a fault.
public List<MyDTO> GetEntitiesMatchingFilter(string filter)
This operation is being asked to return a list of entities matching the filter. If there are no entities matching the filter, then this is not a reason to return a fault. It's a normal, expected result.
On the other hand, if the operation cannot return any entities because of a failure to connect to the database, that's a good reason to return a fault.
I have my own wcf service class which should as result return string with "Everything Save Saccesfully" if ok save data. Otherwise I need to return in this string exception.
string SaveData(Stream stream)
{
string error = "";
try
{
//do saving data
error+="Everything Save Saccefully";
return error;
}
catch(Exception ex)
{
throw ex;
}
finally
{
}
}
It is possible to catch errors occurs in try block and return it in error variable ?
Well, the traditional way that you express the error is simply via an exception - not a return value. Lack of exception should imply "everything went correctly". That's the normal idiomatic way of working.
Now, occasionally it's worth having a method which doesn't throw an exception, but instead returns a success status and potentially a separate result via an out parameter. But that's relatively rare - it's usually for things like parsing, where it's entirely normal for it to fail in hard-to-predict ways when nothing's really wrong other than the input data.
In your case, it looks like this should be a void method which simply throws an exception on error.
Normally I would do as suggested by Jon, but if you really don't want to allow any exceptions to bubble up from your service you could encapsulate your success and (any) failure error information in a class structure like this
public class ErrorInfo
{
public string Message {get; set;}
// TODO: Maybe add in other information about the error?
}
public class SaveResult
{
public bool Success { get; set; }
/// <summary>
/// Set to contain error information if Success = false
/// </summary>
public ErrorInfo ErrorInfo { get; set; }
}
And then...
public SaveResult SaveData(Stream stream)
{
SaveResult saveResult = new SaveResult();
string error = "";
try
{
//do saving data
saveResult.Success = true;
}
catch (Exception ex)
{
saveResult.ErrorInfo = new ErrorInfo { Message = ex.Message };
}
}
The downside of this approach is that your caller must check the Success value after calling SaveData. Failure to do so can result in a bug in your code that will only manifest itself if the save fails.
Alternatively, if you don't handle the exception you get to benefit from one of the useful things about structured exception handling: If the caller forgets to explicitly handle any exception then it will bubble up the call stack and either crash the app or get caught by some higher-level error handling code.
Not necessarily ideal, but generally better than your code silently assuming that something succeeded, when in fact it didn't.
You should use Faults for exceptional results in WCF. I do not see idea why you would need exception in string. But if you absolutely need this, just move return statement to the end and set its value in catch block too.
string SaveData(Stream stream)
{
string error = "";
try
{
//do saving data
error+="Everything Save Saccefully";
}
catch(Exception ex)
{
//throw ex; Do not throw, just return its string representation
error+=ex.ToString();
}
finally
{
}
return error;
}
Try this :
string SaveData(Stream stream)
{
string error;
try
{
//do saving data
error ="Everything saved Successfully";
}
catch(Exception ex)
{
error = ex.Message;
}
return error;
}