I'm just starting the ASP.NET tutorial and I don't understand why there is no return statement in the method:
public async Task OnGetAsync()
{
Movie = await _context.Movie.ToListAsync();
}
Are one line methods automatically returned like arrow statements or does it have to do with the Task in ASP?
Its a model that have property Movie. That property gets set when method OnGetAsync is called. So, you don't need return.
Method return type is Task because it has await. Its analogous to void type if it would be a sync method.
if you want to return the list of Movie
then your function should be :
public async Task<List<Movie>> OnGetAsync()
{
return await _context.Movie.ToListAsync();
}
Related
In my Junit Jupiter API 5.5 test, I am calling my method which internally makes a HTTP call to a remote service.
Now the remote service can be down or behave incorrectly. I want to skip my test in case the remote service is not behaving expectedly.
#Test
void testMe() {
// do something
Result res1 = myObject.retrieveResults(params)
// assert something
Result res2 = myObject.retrieveResults(param2)
//asert on results
}
Result retrieveResults(Parameters param) {
// do something
// call to remote service
// if they do not give result throw CustomException()
// return Result
}
So basically in my test i would want to check if myObject.retrieveResult is throwing CustomException then skip that test, otherwise evaluate normally.
We have 2 different ways to accomplish this tasks in JUnit 5.
For demo purposes, I have created a basic class which sends a request to the url
that is passed as an argument to its call(String url) method and
returns true or false depending on the request result.
The body of the method is irrelevant here.
Using Assumptions.assumeTrue()/assumeFalse() methods
Assumptions class provides us with two overloaded methods - assumeTrue
and assumeFalse. The idea is that, if the assumption is wrong, the test will be skipped.
So, the test will be something like this.
#Test
void call1() {
Assumptions.assumeTrue(new EndpointChecker(), "Endpoint is not available");
Assertions.assertTrue(HttpCaller.call("https://www.google.com"));
}
Here is the code for EndpointChecker class.
static class EndpointChecker implements BooleanSupplier {
#Override
public boolean getAsBoolean() {
// check the endpoint here and return either true or false
return false;
}
}
When the test is run, the availability of the endpoint will be checked first, if it is up, then the test will run.
Using JUnit 5 extension mechanisms.
So, let's start with creating the annotation. It is pretty straightforward.
#Retention(RetentionPolicy.RUNTIME)
#ExtendWith(EndpointAvailabilityCondition.class)
public #interface SkipWhenEndpointUnavailable {
String uri();
}
And EndpointAvailabilityCondition class. Even though, it looks big, overall logic is very simple.
import static org.junit.platform.commons.util.AnnotationUtils.findAnnotation;
public class EndpointAvailabilityCondition implements ExecutionCondition {
#Override
public ConditionEvaluationResult evaluateExecutionCondition(ExtensionContext context) {
final var optional = findAnnotation(context.getElement(), SkipWhenEndpointUnavailable.class);
if (optional.isPresent()) {
final SkipWhenEndpointUnavailable annotation = optional.get();
final String uri = annotation.uri();
// check connection here start
boolean result = false; // dummy value
// check connection here end
if (result) {
return ConditionEvaluationResult.enabled("Connection is up");
} else {
return ConditionEvaluationResult.disabled("Connection is down");
}
}
return ConditionEvaluationResult.enabled("No assumptions, moving on...");
}
}
Hence, we can do the following in our tests.
#Test
#SkipWhenEndpointUnavailable(uri = "https://www.google.com")
void call2() {
Assertions.assertTrue(HttpCaller.call("https://www.google.com"));
}
We can go ahead and add #Test annotation over #SkipWhenEndpointUnavailable and remove it from our test code. Like, so:
#Retention(RetentionPolicy.RUNTIME)
#ExtendWith(EndpointAvailabilityCondition.class)
#Test
public #interface SkipWhenEndpointUnavailable {
String uri();
}
class HttpCallerTest {
#SkipWhenEndpointUnavailable(uri = "https://www.google.com")
void call2() {
Assertions.assertTrue(HttpCaller.call("https://www.google.com"));
}
}
I hope it helps.
I am hoping someone can shed some light on a problem I am having. I am writing a Windows Store app which on startup needs to copy a "seed" database from the App installation folder Windows.ApplicationModel.Package.Current.InstalledLocation.Path to the Local data folder Windows.Storage.ApplicationData.Current.LocalFolder. To do this I have used the following called from my OnNavigatedTo method in Main().
protected override void OnNavigatedTo(NavigationEventArgs e)
{
//Calls method in Dal Class which ensures database is in correct location and if not copies it
Dal.LoadData();
RefreshScenarioList();
ScenarioList.SelectedIndex = 0; //this is the Default Item
}
public static async void LoadData()
{
await CopyIfNotExists(dbName);
}
private static async Task CopyIfNotExists(string dbName)
{
if (await GetIfFileExistsAsync(dbName) == null)
{
StorageFile seedFile = await StorageFile.GetFileFromPathAsync(
Path.Combine(Windows.ApplicationModel.Package.Current.InstalledLocation.Path,
dbName));
await seedFile.CopyAsync(Windows.Storage.ApplicationData.Current.LocalFolder);
}
}
private static async Task<StorageFile> GetIfFileExistsAsync(string key)
{
try
{
return await ApplicationData.Current.LocalFolder.GetFileAsync(key);
}
catch (FileNotFoundException) { return default(StorageFile); }
}
Please also note that I have also used GetFileAsync and also tried using a uri to obtain the seed file (to see if there was any difference). With the combination here I seem to be having the highest success rate. This seems to work 2-3 times out of every 4 tries but I would be much more comfortable with something that works 100% of the time. It only needs to copy the database once on startup.
When it doesn't work it "seems" to never return (ie CopyIfNotExists never seems to complete). The issue appears to be in the CopyIfNotExists method. The problem is that virtually the next line of code in my OnNavigatedTo method is a query on the database and it falls over when the database doesn't copy.
Any insights that anyone may have would be greatly appreciated.
From what I can see, the problem here is that your use of async and await does not go as far up the call stack as it can.
When writing async code, there are a couple of general rules to follow -
If a function Foo uses the async keyword, then any other function that calls Foo must also use the async keyword.
Never use async void in a function signature - use async Task instead. The exceptions are:
your function is an event handler (e.g. button press)
or you are overriding a method that happens to return void
Let's take a look at the method signatures on your call stack. OnNavigatedTo is shown here at the top:
override void OnNavigatedTo()
async void LoadData()
async Task CopyIfNotExists()
async Task<StorageFile> GetIfFileExistsAsync()
The bottom two methods of the call stack uses async Task in the method signatures. Above those on the call stack is LoadData, which follows rule 1 above, but breaks rule 2. LoadData should be changed to this:
public static async Task LoadData()
{
await CopyIfNotExists(dbName);
}
Next we try to make OnNavigatedTo follow the above rules:
async protected override void OnNavigatedTo(NavigationEventArgs e)
Note that we cannot use async Task, since your method is an override. We have to stick to async void.
Now you just need to add await to your LoadData call since it is an async method. We do this so that your program waits for LoadData to complete prior to calling RefreshScenarioList:
async protected override void OnNavigatedTo(NavigationEventArgs e)
{
//Calls method in Dal Class which ensures database is in correct location and if not copies it
await Dal.LoadData();
RefreshScenarioList();
ScenarioList.SelectedIndex = 0; //this is the Default Item
}
Now you will want to also ensure that the call stack for RefreshScenarioList follows the async rules above.
One more thing that I noticed with your code. In Windows 8.1 or later, you should use TryGetItemAsync instead of GetFileAsync:
private static async Task<StorageFile> GetIfFileExistsAsync(string key)
{
return await ApplicationData.Current.LocalFolder.TryGetItemAsync(key) as StorageFile;
}
The new method returns null when it cannot find a file. The old method throws an exception. Throwing exceptions on a UI thread can cause your UI to stall, so it is advantageous to use the new method.
I am creating PCL using MvvmCross.
I am calling one method in Command which fetch data by calling web service.
I want to do this data fetch operation asynchronously.
How can I apply async and await to methods in Command ?
Any ideas?
There are a couple of options.
1) You can implement the command with an async void method/delegate. If you do this, I recommend you have the async void method just await a Task from an async Task method that contains the actual logic because async Task methods are easier to unit test. Also, you'll need a try/catch for proper error handling.
2) You can have the command just start a method returning Task<T> and expose the result of the operation as a property using NotifyTaskCompletion from my AsyncEx library. This allows you to data bind to the result as well as errors. However, AsyncEx does not support all the platforms MvvmCross does (in particular, Windows Phone 7.0 and Xamarin.Mac).
Update - examples:
Using the first option:
public ICommand ContactSlodgeCommand
{
get
{
return new MvxCommand(async () =>
{
await ComposeEmailAsync("me#slodge.com", "About MvvmCross and the SQL Bits app", "I've got a question"));
}
}
}
Using the second option:
private INotifyTaskCompletion<MyResource> _resource;
public INotifyTaskCompletion<MyResource> Resource
{
get { return _resource; }
set { _resource = value; NotifyPropertyChanged(); }
}
public ICommand LoadResourceCommand
{
get
{
return new MvxCommand(() =>
{
Resource = NotifyTaskCompletion.Create(LoadResourceAsync());
}
}
}
You should do data-binding for that property by using databinding of mvvmcross and use async await or Task like #Stephen Cleary said
void FetchData(Action<T> callback)
{
Task.Run<T>(()=>{
return Service.GetDataSynchronous();
}).ContinueWith((data)=>{
callback(data);
});
}
public MvxCommand
{
get
{
return new MvxCommand(()=>{
FetchData((data)=>{
this.Property = data;
});
});
}
}
If I write something like this:
verify().that( mockPromise.handleFault( any() ))
it works fine to tell me that 'handleFault' was invoked.
But later I want to invoke the fault handler function that was passed in. The handler will be a private function so there isn't another way to access it.
In Java Mockito, the feature you're looking for is called ArgumentCaptor. In short, it's a special kind of Matcher (like any()) that matches any type of object and keeps the object it "matches" in a variable.
Unfortunately, it looks like it's not available in Flex yet.
The good news is that if you feel like it, you can probably write an implementation of the Matcher interface that does exactly that--save its most recent value and return true--in fifteen minutes or so. :)
Good luck!
Based on Jeff's answer, I did this:
import org.mockito.api.Matcher;
class ArgumentCaptor implements Matcher
{
private var _value:*;
public function ArgumentCaptor()
{
}
public function get value():*
{
return _value;
}
public function describe():String
{
return "";
}
public function matches(value:*):Boolean
{
_value = value;
return true;
}
}
which can be used like:
var argCaptor:ArgumentCaptor = new ArgumentCaptor();
verify().that( mockPromise.handleFault( argThat(argCaptor) ));
argCaptor.value; // the argument
I just started using LINQ to SQL classes, and really like how this helps me write readable code.
In the documentation, typical examples state that to do custom validation, you create a partial class as so::
partial class Customer
{
partial void OnCustomerIDChanging(string value)
{
if (value=="BADVALUE") throw new NotImplementedException("CustomerID Invalid");
}
}
And similarly for other fields...
And then in the codebehind, i put something like this to display the error message and keep the user on same page so to correct the mistake.
public void CustomerListView_OnItemInserted(object sender, ListViewInsertedEventArgs e)
{
string errorString = "";
if (e.Exception != null)
{
e.KeepInInsertMode = true;
errorString += e.Exception.Message;
e.ExceptionHandled = true;
}
else errorString += "Successfully inserted Customer Data" + "\n";
errorMessage.Text = errorString;
}
Okay, that's easy, but then it stops validating the rest of the fields as soon as the first Exception is thrown!! Mean if the user made mode than one mistake, she/he/it will only be notified of the first error.
Is there another way to check all the input and show the errors in each ?
Any suggestions appreciated, thanks.
This looks like a job for the Enterprise Library Validation Application Block (VAB). VAB has been designed to return all errors. Besides this, it doesn't thrown an exception, so you can simply ask it to validate the type for you.
When you decide to use the VAB, I advise you to -not- use the OnXXXChanging and OnValidate methods of LINQ to SQL. It's best to override the SubmitChange(ConflictMode) method on the DataContext class to call into VAB's validation API. This keeps your validation logic out of your business entities, which keeps your entities clean.
Look at the following example:
public partial class NorthwindDataContext
{
public ValidationResult[] Validate()
{
return invalidResults = (
from entity in this.GetChangedEntities()
let type = entity.GetType()
let validator = ValidationFactory.CreateValidator(type)
let results = validator.Validate(entity)
where !results.IsValid
from result in results
select result).ToArray();
}
public override void SubmitChanges(ConflictMode failureMode)
{
ValidationResult[] this.Validate();
if (invalidResults.Length > 0)
{
// You should define this exception type
throw new ValidationException(invalidResults);
}
base.SubmitChanges(failureMode);
}
private IEnumerable<object> GetChangedEntities()
{
ChangeSet changes = this.GetChangeSet();
return changes.Inserts.Concat(changes.Updates);
}
}
[Serializable]
public class ValidationException : Exception
{
public ValidationException(IEnumerable<ValidationResult> results)
: base("There are validation errors.")
{
this.Results = new ReadOnlyCollection<ValidationResult>(
results.ToArray());
}
public ReadOnlyCollection<ValidationResult> Results
{
get; private set;
}
}
Calling the Validate() method will return a collection of all errors, but rather than calling Validate(), I'd simply call SubmitChanges() when you're ready to persist. SubmitChanges() will now check for errors and throw an exception when one of the entities is invalid. Because the list of errors is sent to the ValidationException, you can iterate over the errors higher up the call stack, and present them to the user, as follows:
try
{
db.SubmitChanges();
}
catch (ValidationException vex)
{
ShowErrors(vex.ValidationErrors);
}
private static void ShowErrors(IEnumerable<ValidationResult> errors)
{
foreach(var error in errors)
{
Console.WriteLine("{0}: {1}", error.Key, error.message);
}
}
When you use this approach you make sure that your entities are always validated before saving them to the database
Here is a good article that explains how to integrate VAB with LINQ to SQL. You should definitely read it if you want to use VAB with LINQ to SQL.
Not with LINQ. Presumably you would validate the input before giving it to LINQ.
What you're seeing is natural behaviour with exceptions.
I figured it out. Instead of throwing an exception at first failed validation, i store an error message in a class with static variable. to do this, i extend the DataContext class like this::
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
/// <summary>
/// Summary description for SalesClassesDataContext
/// </summary>
public partial class SalesClassesDataContext
{
public class ErrorBox
{
private static List<string> Messages = new List<string>();
public void addMessage(string message)
{
Messages.Add(message);
}
public List<string> getMessages()
{
return Messages;
}
}
}
in the classes corresponding to each table, i would inherit the newly defined class like this::
public partial class Customer : SalesClassesDataContext.ErrorBox
only in the function OnValidate i would throw an exception in case the number of errors is not 0. Hence not attempting to insert, and keeping the user on same input page, without loosing the data they entered.