C
C#15mo ago
Haqz

✅ xUnit | Saved entity not found.

Hello, this time coming with yet again problems with tests. So I'm testing my deleting route, so i create the related entity in database, get it's hash - the delete route takes hash as an path parameter, and pas it down to the repository for delete. The creation works, checked the context if it exists and it does, but for whatever reason it cannot be found and deleted. I think it may be problem with how i've set up the contexts. Repository
public void Delete(string hash)
{
var report = (from d in _dataContext.PaymentDatas
where d.Hash == hash
select d).Single();

_dataContext.PaymentDatas.Remove(report);
_dataContext.SaveChanges();
}
public void Delete(string hash)
{
var report = (from d in _dataContext.PaymentDatas
where d.Hash == hash
select d).Single();

_dataContext.PaymentDatas.Remove(report);
_dataContext.SaveChanges();
}
Test
private readonly DataContext context;

public InternalController(ITestOutputHelper output)
{
_factory = new CustomWebAppFactory();
_client = _factory.CreateClient();
this.output = output;

var path = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
var dbOption = new DbContextOptionsBuilder<DataContext>()
.UseSqlite($"Data Source={Path.Join(path, "WebMinRouteGroup_tests.db")}");
context = new DataContext(dbOption.Options);
//context.Database.Migrate();

}
private readonly DataContext context;

public InternalController(ITestOutputHelper output)
{
_factory = new CustomWebAppFactory();
_client = _factory.CreateClient();
this.output = output;

var path = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
var dbOption = new DbContextOptionsBuilder<DataContext>()
.UseSqlite($"Data Source={Path.Join(path, "WebMinRouteGroup_tests.db")}");
context = new DataContext(dbOption.Options);
//context.Database.Migrate();

}
21 Replies
Haqz
HaqzOP15mo ago
[Fact]
public async void DeletePayment_Passes_WithCorrectData()
{
//Arrange
var payment = context.PaymentDatas.Add(new PaymentData
{
Hash = "dupa",
RelatedHash= Guid.NewGuid().ToString(),
Sum = 1000,
MappedStatus= 0,
});
context.SaveChanges();
var definition = new { Message = "" };
//Act
var response = await _client.DeleteAsync("/payment/"+payment.Entity.Hash);
var test = context.PaymentDatas.Single(x => x.Hash == payment.Entity.Hash);
var entityEntry = context.Entry(test);
output.WriteLine(entityEntry.State.ToString());
output.WriteLine(await response.Content.ReadAsStringAsync());
var responsePaymentData = JsonConvert.DeserializeAnonymousType(await response.Content.ReadAsStringAsync(), definition);
output.WriteLine(response.ToString());
//Assert
//Assert.Equal(System.Net.HttpStatusCode.OK, response.StatusCode);
//Assert.NotEmpty(responsePaymentData.Message);

}
[Fact]
public async void DeletePayment_Passes_WithCorrectData()
{
//Arrange
var payment = context.PaymentDatas.Add(new PaymentData
{
Hash = "dupa",
RelatedHash= Guid.NewGuid().ToString(),
Sum = 1000,
MappedStatus= 0,
});
context.SaveChanges();
var definition = new { Message = "" };
//Act
var response = await _client.DeleteAsync("/payment/"+payment.Entity.Hash);
var test = context.PaymentDatas.Single(x => x.Hash == payment.Entity.Hash);
var entityEntry = context.Entry(test);
output.WriteLine(entityEntry.State.ToString());
output.WriteLine(await response.Content.ReadAsStringAsync());
var responsePaymentData = JsonConvert.DeserializeAnonymousType(await response.Content.ReadAsStringAsync(), definition);
output.WriteLine(response.ToString());
//Assert
//Assert.Equal(System.Net.HttpStatusCode.OK, response.StatusCode);
//Assert.NotEmpty(responsePaymentData.Message);

}
Pobiega
Pobiega15mo ago
what errors do you get? Or what status code does the http method you invoke respond with?
Haqz
HaqzOP15mo ago
Oh sorry forgot to include that: Right now:
System.ArgumentNullException: Value cannot be null. (Parameter 'entity')
at Microsoft.EntityFrameworkCore.Utilities.Check.NotNull[T](T value, String parameterName)
at Microsoft.EntityFrameworkCore.Internal.InternalDbSet`1.Remove(TEntity entity)
at service__payments.Repositories.PaymentDataRepository.Delete(String hash)
System.ArgumentNullException: Value cannot be null. (Parameter 'entity')
at Microsoft.EntityFrameworkCore.Utilities.Check.NotNull[T](T value, String parameterName)
at Microsoft.EntityFrameworkCore.Internal.InternalDbSet`1.Remove(TEntity entity)
at service__payments.Repositories.PaymentDataRepository.Delete(String hash)
But in some iteration of my tries it also said Sequence is empty or something like that
Pobiega
Pobiega15mo ago
okay, Sequence is empty is from .Single() not finding anything and value cannot be null is almost guaranteed from _dataContext.PaymentDatas.Remove(report); where report is null put some breakpoints down and check whats going on you said you verified that the
//Arrange
var payment = context.PaymentDatas.Add(new PaymentData
{
Hash = "dupa",
RelatedHash= Guid.NewGuid().ToString(),
Sum = 1000,
MappedStatus= 0,
});
context.SaveChanges();
//Arrange
var payment = context.PaymentDatas.Add(new PaymentData
{
Hash = "dupa",
RelatedHash= Guid.NewGuid().ToString(),
Sum = 1000,
MappedStatus= 0,
});
context.SaveChanges();
stuff worked, for sure? ie, putting a breakpoint after that savechanges and manually looked?
Haqz
HaqzOP15mo ago
Oke, give me a minute for that Yes, i especially changed the sqlite file name to something else and ran only this test, and it was created in it
Pobiega
Pobiega15mo ago
okay
Haqz
HaqzOP15mo ago
Huh, it suddenly started working?
Pobiega
Pobiega15mo ago
you sure you had the latest version compiled and running? because value cannot be null should not be possible, since you fetched the value yusing Single() and not SingleOrDefault()
Haqz
HaqzOP15mo ago
I think so? Well if running single test doesnt recompile the code then i guess i wouldnt have the updated code I hate when stuff suddenly starts working because i dont know what was broken notLikeCat
Pobiega
Pobiega15mo ago
¯\_(ツ)_/¯ depends how you run it via dotnet test im not sure it rebuilds everything
Haqz
HaqzOP15mo ago
Running it through visual studio so no idea either
Pobiega
Pobiega15mo ago
okay, then it should, I imagine but not 100%
Haqz
HaqzOP15mo ago
Well nonetheless problem is gone for now, thanks once again!
Pobiega
Pobiega15mo ago
yay
Haqz
HaqzOP15mo ago
Oh on the topic of tests, i was wondering, if what i did to get the context in tests is the right way?
var path = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
var dbOption = new DbContextOptionsBuilder<DataContext>()
.UseSqlite($"Data Source={Path.Join(path, "WebMinRouteGroup_tests.db")}");
context = new DataContext(dbOption.Options);
var path = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
var dbOption = new DbContextOptionsBuilder<DataContext>()
.UseSqlite($"Data Source={Path.Join(path, "WebMinRouteGroup_tests.db")}");
context = new DataContext(dbOption.Options);
this sits in constructor of test, is there maybe better way to do it so i can access it in each and every test i create?
Pobiega
Pobiega15mo ago
uhm, its certainly one way I'd probably just resolve it from the service provider
Haqz
HaqzOP15mo ago
So instead of calling the context dfirectly i should use the service for example creation of entities?
Pobiega
Pobiega15mo ago
no, using the context is fine I would highly recommend you stop using query syntax thou 😄
Haqz
HaqzOP15mo ago
Oh thaqt was just me looking for any option that would fetch, i will switch to Fluent API asap
Pobiega
Pobiega15mo ago
var report = (from d in _dataContext.PaymentDatas
where d.Hash == hash
select d).Single(); // BAD
var report = _dataContext.PaymentDatas.Where(x => x.Hash == hash).Single(); // better
var report = (from d in _dataContext.PaymentDatas
where d.Hash == hash
select d).Single(); // BAD
var report = _dataContext.PaymentDatas.Where(x => x.Hash == hash).Single(); // better
and prefer to use the async methods so await... SingleAsync();
Haqz
HaqzOP15mo ago
HmmNoted that settles my questions, for now, thanks once again for quick help!
Want results from more Discord servers?
Add your server