retrieve int value from async task - vb.net

I have an async task in a separate project that I need to call from another project but Im not sure how to accomplish that.
The async method is
public async Task<int> InsertNewPasswordResetRequest(UserPasswordReset upr)
{
string commandText = "Insert Into passwordresetrequests (reset_username, ResetToken, ResetRequestTime, ResetRequestTimeout) values(#username,#rt,#rrt,#rrtout);";
var parameters = new Dictionary<string, object>() {
{ "#username", upr.ResetUsername },
{ "#rt", upr.ResetToken },
{ "#rrt", upr.ResetRequestTime },
{ "#rrtout", upr.ResetRequestTimeout }
};
return await Task.FromResult( _database.Execute(commandText, parameters, false));
}
I am trying to call it from another project like so
Dim success As Integer = prr.InsertNewPasswordResetRequest(upr).FromResult()
I know its returning a task but how do I extract the int value from it?

You can await of your task if you want to run it async
Dim success As Integer = Await prr.InsertNewPasswordResetRequest(upr)
or run task synchronously as
Dim success As Integer = prr.InsertNewPasswordResetRequest(upr).Result

The recommended way is to await the results of the InsertNewPasswordResetRequest method. You can also call the Result property on the returned Task<int> but that could lead to your code blocking if you're executing within a synchronization context.
int result = await InsertNewPasswordResetRequest(...);
An additional note: There is no need to await Task.FromResult in that method. Simply remove the async modifier from the method signature and the await keyword and return Task.FromResult directly.
An additional note: If possible, consider making InsertNewPasswordResetRequest non-async completely since it doesn't execute any asynchronous code.
Edit for VB.NET calling code:
Dim result As Integer = Await InsertNewPasswordResetRequest(...)

Related

How to fill a Mock<DbSet> in Nunit with Moq?

I am trying to fill a mock dbset with a testentity but I only get exception after exception. I am very new to Nunit testing and haven't really got the hang of it. I am trying to test a simple delete method in my repository, here is the code for the method:
public async Task DeleteQuestion(Question questionToRemove)
{
if (questionToRemove is not null)
{
var questionsAnswers = await _context.Answers.Where(a => a.Question == questionToRemove).ToListAsync();
foreach (Answer a in questionsAnswers)
{
_context.Answers.Remove(a);
await _context.SaveChangesAsync();
}
_context.Questions.Remove(questionToRemove);
await _context.SaveChangesAsync();
var questions = await _context.Questions.Where(q => q.Quiz == questionToRemove.Quiz).ToListAsync();
int order = 1;
foreach (Question question in questions)
{
question.QuestionOrderId = order;
await _context.SaveChangesAsync();
order++;
}
}
}
And here is the test that I have written:
public async Task DeleteQuestionFunction()
{
//Arrange
Question testQuestion = new Question { QuestionId = 1, QuestionText = "Test" };
Answer testAnswer = new Answer { Question = testQuestion, AnswerId = 1, AnswerText = "TestAnswer" };
_appDBContextMock.SetupAdd(x => x.Questions.Add(testQuestion));
_appDBContextMock.SetupAdd(x => x.Answers.Add(testAnswer));
//Act
var questionListcomponent = new QuestionListComponent();
questionListcomponent.DeleteQuestion(testQuestion);
var testresult = await _questionRepositoryMock.Object.GetQuestionById(testQuestion.QuestionId);
//Assert
Assert.That(testresult, Is.Null);
}
When I only used the Setup method I got this exception:
System.NotSupportedException : Unsupported expression: x =>
x.Questions Non-overridable members (here: AppDbContext.get_Questions)
may not be used in setup / verification expressions.
and right now with the SetupAdd function I get this exception:
System.ArgumentException : Can not instantiate proxy of class:
TietoQuiz.Models.DbContexts.AppDbContext. Could not find a
parameterless constructor. (Parameter 'constructorArguments')
I think my problem is that I don't know how to set up a mock dbset properly. I tried to Google, but I found so many different ways and so many comments saying "that is not recommended/ the wrong way"! It is very confusing for a newbie, so I hope someone here can help!
If you want to write a test by using a context, you must create your own context and verify the data after running it. You cannot use mocks with non overridable methods.
You must use a temporary file to create this context not to change your production database.

How to synchronize web api calls to a database

I have the following problem:
I have a async web api which updates certain fields of a mongo document. It first retrieves the document updates the fields and then saves the document asynchronously to the database. How do I ensure that if the api is called multiple times in succession, one call will not overwrite the results of a previous call ?
public async Task<ActionResult> UpdateAsync(string id , string b)
{
//this queries the mongo db and returns the document
var q = await _mongoService.FindAsync(id);
q.someField = b;
await _mongoService.UpdateAsync(q);
}
When called multiple times, I first get q, then when one of the calls saves q, but then another call to the api can overwrite the first q.
How do i synchronize the finds and updates ?
The following solution works but i am afraid that this is not scalable
static object _locker = new object();
public async Task<ActionResult> UpdateAsync(string id , string b)
{
await Task.Run(() =>
lock (_locker) {
var q = _mongoService.Find(id);
q.someField = b;
_mongoService.Update(q);
}
}
Another option is using a semaphore
private static SemaphoreSlim _mutex = new SemaphoreSlim(1);
public async Task<ActionResult> UpdateAsync(string id , string b)
{
_mutex.WaitAsync();
//this queries the mongo db and returns the document
var q = await _mongoService.FindAsync(id);
q.someField = b;
await _mongoService.UpdateAsync(q);
_mutex.Release()
}
Not sure if these are the best solutions

Since 'func' is an async method that returns 'Task',a return keyword must not be followed by an object expression. Did you intend to return 'Task<T>'?

Hello My Program got this error and i dont know why?
Since 'InsertToHomeSecondPagesTableJob.Execute(IJobExecutionContext)' is an async method that returns 'Task', a return keyword must not be followed by an object expression. Did you intend to return 'Task'?
this is my code
public async Task Execute(IJobExecutionContext context)
{
var PagesScoreNewsHomePageTable = new PagesScoreNewsHomePageTable()
{
PagesID = 1,
UserID = 22,
Author = "jack"
};
_db.AddAsync(PagesScoreNewsHomePageTable);
_db.SaveChangesAsync();
return Task.CompletedTask;
}
how can i solve this error?
The simple and recommended way to solve this problem is using await keywords.
The async and await keywords in C# are the heart of async programming.
By using those two keywords, you can use resources in .NET Framework,
.NET Core, or the Windows Runtime to create an asynchronous method
almost as easily as you create a synchronous method.
You just need to change your code like:
public async Task Execute(IJobExecutionContext context)
{
var PagesScoreNewsHomePageTable = new PagesScoreNewsHomePageTable()
{
PagesID = 1,
UserID = 22,
Author = "jack"
};
await _db.AddAsync(PagesScoreNewsHomePageTable);
await _db.SaveChangesAsync();
}
More details about async you can refer to this Docs.

How to fetch initial data using provider in flutter effectievly

Recently, i did a flutter course.
The instructor was making the get request from an API so difficult. For a hybrid framework like flutter i never thought it's so difficult.
below are my code. I am using provider for state management.
Future<void> fetchAndSetProducts() async {
try {
const url = 'fetch-url';
final response = await http.get(url);
final data = json.decode(response.body) as Map<String, dynamic>;
final List<Product> loadedProducts = [];
data.forEach((key, value) {
loadedProducts.add(Product(
id: key,
title: value['title'],
description: value['description'],
imageUrl: value['imageUrl'],
price: value['price'],
isFavorite: value['isFavorite'],
));
});
_items = loadedProducts;
notifyListeners();
} catch (error) {
throw (error);
}
}
And in the products overview screen were I am showing the products page this method is called like below:
bool _isInit = true;
bool _isLoading = false;
#override
void didChangeDependencies() {
if (_isInit) {
setState(() {
_isLoading = true;
});
Provider.of<Products>(context).fetchAndSetProducts().then((_) => {
setState(() {
_isLoading = false;
})
});
}
_isInit = false;
super.didChangeDependencies();
}
The other method included a sneaky way of using duration of zero just like we use in javascript set timeout giving a zero time.
It's worth noting that in didChangeDependencies we could not use async await, so most probably a call back hell awaits.
Also a variable needs to be initialized just for calling the api once upon loading.
Is there no easy solution to this? Or an industry way of dealing with this?
here is a minimal working example of what you can do, it's not the best thing in the world, but this is what works for me, let me know if you can make it any better.
The answer to your problem is really simple, BUT, you need to rearrange some stuff first.
A Flutter app can be split into multiple layers which are (just for example) data, state management and UI, in the data layer you will have all methods that communicate with the API, and you call them inside the state management solution (which is provider in your case), the result will be accessible from the provider which will save the data in a variable, then the UI will be able to retrieve these data from the provider, this seems a bit redundant I know, but there is a reason why we do that, if you put the API call inside the provider itself, and there is somewhere else in your app that uses the same endpoint then you will have duplicate code, as for the provider, it's the place where your data is stored in the runtime, these data are what makes the state of your app, finally, the UI can handle displaying data from the provider easily, just make a boolean in the provider that indicates if the API call is executing/loading or not, and inside the consumer in the UI display different widgets based on the boolean.
If we were to visualize the flow of the operation it would be like this:
1- action from the UI that triggers a method from the provider.
2- inside the provider method you will set the boolean indicating that the API call is executing to true and call notifyListeners().
3- call the API request and call .then() on it.
4- inside the .then() set the boolean to false to notify that the call is over and set the received data to a variable inside the provider and call notifyListeners again.
5- in the UI you should have a consumer listening to your provider and handling the boolean, if its true then display a CircularProgressIndicator for example, and if it's false then display your desired widget
Regarding the context in the initState you can fix this problem in 3 ways:
1- using WidgetsBinding.instance
.addPostFrameCallback((_) => yourProviderFunction(context));
2- by registering your provider in a service locator so you don't have to use a context at all. (which is what I used in the example project I posted above)
3- by executing the desired function in the constructor of the provider, so when its initialized the API request will be called
Is this the Academind course?
Also this is the correct way.
For using a Provider you need the context.
EDIT: Added BaselAbuhadrous' comment to the answer.
You need to use didChangeDependencies because the initState actually provides the context, but the screen layout isn't built yet, so you get an error, but if you used WidgetsBindings.instance and call the provider inside of it, then you won't get the error.
//your model , product_model.dart
import 'dart:convert';
List<Product> availableTicketsFromJson(String str) => List<Product>.from(json.decode(str).map((x) => Product.fromJson(x)));
class Product {
String title;
String description;
String imageUrl;
double price;
bool isFavorite;
Product(
{this.title,
this.description,
this.imageUrl,
this.price,
this.isFavorite});
factory Product.fromJson(Map<String, dynamic> json) => Product(
title: json['title'] as String,
description: json['description'] as String,
imageUrl: json['imageUrl'] as String,
price: json['price'] as double,
isFavorite: json['isFavorite'] as bool,
);
}
//viewmodel class
final String url = "test.com";
Future<List<Product> fetchProducts() async {
List<Product> products = List<Product>();
try {
final request = await http.get(url);
if(request.statusCode == 200) {
products = productsFromJson(request.body.toString());
notifyListeners();
} else {
print(request.statusCode.toString());
}
} catch(e) {
return List<Product>();
}
return products;
}
//fetch_data.dart
Create your instance of provider in the page that you wanna fetch the data:
Under State<yourWidget>
=> FetchDataViewModel _model;
List<Product> products = [];
under build method
=> _model = Provider.of<FetchDataViewModel>(context,listen: false);
Make a http request with FutureBuilder
FutureBuilder(future:_model.fetchProducts()),
builder: (context,snapshot)){
if(snapshot.connectionState == ConnectionState.done) {
products = snapshot.data;
if(products.length > 0) {
return ListView.builder(
itemCount: products.length,
itemBuilder : (context,index) {
return _items();
}
);
} else {return _noSavedDataWidget();}
}
}
You can test such a code
sometimes
Provider.of<'providerClassName'>(context, listen : false).'providerFunction'
might help.

Structuring tests (or property) for this reactive ui scenario

I'm not sure the correct way to structure this test. I've got a view model here:
public class ViewModel
{
public ReactiveCommand PerformSearchCommand { get; private set; }
private readonly ObservableAsPropertyHelper<bool> _IsBusy;
public bool IsBusy
{
get { return _IsBusy.Value; }
}
public ViewModel(IAdventureWorksRepository _awRepository)
{
PerformSearchCommand = new ReactiveCommand();
PerformSearchCommand.RegisterAsyncFunction((x) =>
{
return _awRepository.vIndividualCustomers.Take(1000).ToList();
}).Subscribe(rval =>
{
CustomerList = rval;
SelectedCustomer = CustomerList.FirstOrDefault();
});
PerformSearchCommand.IsExecuting.ToProperty(this, x => x.IsBusy, out _IsBusy);
PerformSearchCommand.Execute(null); // begin executing immediately
}
}
The dependency is a data access object to AdventureWorks
public interface IAdventureWorksRepository
{
IQueryable<vIndividualCustomer> vIndividualCustomers { get; }
}
Finally, my test looks something like this:
[TestMethod]
public void TestTiming()
{
new TestScheduler().With(sched =>
{
var repoMock = new Mock<IAdventureWorksRepository>();
repoMock.Setup(x => x.vIndividualCustomers).Returns(() =>
{
return new vIndividualCustomer[] {
new vIndividualCustomer { FirstName = "John", LastName = "Doe" }
};
});
var vm = new ViewModel(repoMock.Object);
Assert.AreEqual(true, vm.IsBusy); //fails?
Assert.AreEqual(1, vm.CustomerList.Count); //also fails, so it's not like the whole thing ran already
sched.AdvanceTo(2);
Assert.AreEqual(1, vm.CustomerList.Count); // success
// now the customer list is set at tick 2 (not at 1?)
// IsBusy was NEVER true.
});
}
So the viewmodel should immediately begin searching upon load
My immediate problem is that the IsBusy property doesn't seem to get set in the testing scheduler, even though it seems to work fine when I run the code normally. Am I using the ToProperty method correctly in the view model?
More generally, what is the proper way to do the full 'time travel' testing when my object under test has a dependency like this? The issue is that unlike most testing examples I'm seeing, the called interface is not an IObservable. It's just a synchronous query, used asynchronously in my view model. Of course in the view model test, I can mock the query to do whatever rx things I want. How would I set this up if I wanted the query to last 200 ticks, for example?
So, you've got a few things in your code that is stopping you from getting things to work correctly:
Don't invoke commands in ViewModel Constructors
First, calling Execute in the constructor means you'll never see the state change. The best pattern is to write that command but not execute it in the VM immediately, then in the View:
this.WhenAnyValue(x => x.ViewModel)
.InvokeCommand(this, x => x.ViewModel.PerformSearchCommand);
Move the clock after async actions
Ok, now that we can properly test the before and after state, we have to realize that after every time we do something that normally would be async, we have to advance the scheduler if we use TestScheduler. This means, that when we invoke the command, we should immediately advance the clock:
Assert.IsTrue(vm.PerformSearchCommand.CanExecute(null));
vm.PerformSearchCommand.Execute(null);
sched.AdvanceByMs(10);
Can't test Time Travel without IObservable
However, the trick is, your mock executes code immediately, there's no delay, so you'll never see it be busy. It just returns a canned value. Unfortunately, injecting the Repository makes this difficult to test if you want to see IsBusy toggle.
So, let's rig the constructor a little bit:
public ViewModel(IAdventureWorksRepository _awRepository, Func<IObservable<List<Customer>>> searchCommand = null)
{
PerformSearchCommand = new ReactiveCommand();
searchCommand = searchCommand ?? () => Observable.Start(() => {
return _awRepository.vIndividualCustomers.Take(1000).ToList();
}, RxApp.TaskPoolScheduler);
PerformSearchCommand.RegisterAsync(searchCommand)
.Subscribe(rval => {
CustomerList = rval;
SelectedCustomer = CustomerList.FirstOrDefault();
});
PerformSearchCommand.IsExecuting
.ToProperty(this, x => x.IsBusy, out _IsBusy);
}
Set up the test now
Now, we can set up the test, to replace PerformSearchCommand's action with something that has a delay on it:
new TestScheduler().With(sched =>
{
var repoMock = new Mock<IAdventureWorksRepository>();
var vm = new ViewModel(repoMock.Object, () =>
Observable.Return(new[] { new vIndividualCustomer(), })
.Delay(TimeSpan.FromSeconds(1.0), sched));
Assert.AreEqual(false, vm.IsBusy);
Assert.AreEqual(0, vm.CustomerList.Count);
vm.PerformSearchCommand.Execute(null);
sched.AdvanceByMs(10);
// We should be busy, we haven't finished yet - no customers
Assert.AreEqual(true, vm.IsBusy);
Assert.AreEqual(0, vm.CustomerList.Count);
// Skip ahead to after we've returned the customer
sched.AdvanceByMs(1000);
Assert.AreEqual(false, vm.IsBusy);
Assert.AreEqual(1, vm.CustomerList.Count);
});