Reputation: 23
I have the following DbContext
:
public class OrganizerDbContext : IdentityDbContext<AppUser>
{
public OrganizerDbContext(DbContextOptions<OrganizerDbContext> options)
: base(options)
{
}
// list of dbSet<> here
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.Entity<AppUser>()
.HasOne(a => a.Accesses)
.WithOne(a => a.User)
.HasForeignKey<UserAccess>(a => a.UserId);
builder.Entity<AppUser>()
.HasOne(a=>a.EmploymentStatus)
.WithOne(a=>a.User)
.HasForeignKey<EmploymentStatus>(a => a.UserId);
builder.Entity<EmploymentStatus>()
.HasOne(a=>a.Facility)
.WithMany(a=>a.Employments)
.HasForeignKey(a => a.FacilityId);
}
}
In my xUnit test, I used FakeItEasy
and have following code:
[Fact]
public async Task AnnouncerIndex_Test_1()
{
// Arrange
var fakeContext = A.Fake<OrganizerDbContext>();
var fakeUserManager = A.Fake<UserManager<AppUser>>();
var controller = new AnnouncementsController(fakeContext, fakeUserManager);
// Act
var result = await controller.IsUserBlockedFromAccesingAnnouncer();
// Assert
Assert.False(result);
}
The test fails and I get this in test details summary:
Message: FakeItEasy.Core.FakeCreationException : Failed to create fake of type Organizer3.Data.OrganizerDbContext: Below is a list of reasons for failure per attempted constructor: Constructor with signature (Microsoft.EntityFrameworkCore.DbContextOptions
1[Organizer3.Data.OrganizerDbContext]) failed: No constructor matches the passed arguments for constructor. An exception of type System.InvalidOperationException was caught during this call. Its message was: The DbContextOptions passed to the OrganizerDbContextProxy constructor must be a DbContextOptions<OrganizerDbContextProxy>. When registering multiple DbContext types, make sure that the constructor for each context type has a DbContextOptions<TContext> parameter rather than a non-generic DbContextOptions parameter. at Microsoft.EntityFrameworkCore.DbContext..ctor(DbContextOptions options) at Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityUserContext
5..ctor(DbContextOptions options) at Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityDbContext8..ctor(DbContextOptions options) at Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityDbContext
3..ctor(DbContextOptions options) at Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityDbContext1..ctor(DbContextOptions options) at Organizer3.Data.OrganizerDbContext..ctor(DbContextOptions
1 options) in C:\Users\Smokiel\Desktop\Organizer3\Organizer3\Areas\Identity\Data\OrganizerDbContext.cs:line 15 at Castle.Proxies.OrganizerDbContextProxy..ctor(IInterceptor[] , DbContextOptions`1 options)Stack Trace: FailedCreationResult.get_Result() line 82 FakeAndDummyManager.CreateFake(Type typeOfFake, Action`1 optionsBuilder, LoopDetectingResolutionContext resolutionContext) line 42 FakeAndDummyManager.CreateFake(Type typeOfFake, LoopDetectingResolutionContext resolutionContext) line 28 A.FakeT line 31 AnnouncementsControllerTests.AnnouncerIndex_Test_1() line 28 --- End of stack trace from previous location ---
I tried adding empty constructor by adding
public OrganizerDbContext() { }
to DbContext, after running test again i got this summary:
Message: System.ArgumentException : Object 'Organizer3.Controllers.AnnouncementsController' of type Organizer3.Controllers.AnnouncementsController is not recognized as a fake object. Stack Trace: DefaultFakeManagerAccessor.GetFakeManager(Object proxy) line 28 Fake.GetFakeManager(Object fakedObject) line 28 FakeConfigurationManager.GuardAgainstNonFake(Object target) line 83 FakeConfigurationManager.CallTo[T](Expression`1 callSpecification) line 45 A.CallTo[T](Expression`1 callSpecification) line 161 AnnouncementsControllerTests.AnnouncerIndex_Test_1() line 34 --- End of stack trace from previous location ---
I expected to get a dummy context I could use for testing, it wasn't called anywhere outside of controller constructor, and I can't get it running.
Upvotes: 1
Views: 572
Reputation: 11546
as the error indicates
A.Fake<OrganizerDbContext>();
Would not pass the parameters which are required to the constructor of DbContext
you have to pass DbContextOptions<> to the contructor of the dbcontext like below
A.Fake<WebApplication6Context>(x => x.WithArgumentsForConstructor(new object[] { options }));
I tried as below,hopes could help:
The Action in controller :
public List<SomeEntity> GetEntities()
{
return _context.SomeEntity.ToList();
}
The Dbcontext:
public class WebApplication6Context : DbContext
{
public WebApplication6Context (DbContextOptions<WebApplication6Context> options)
: base(options)
{
}
public virtual DbSet<WebApplication6.Models.SomeEntity>? SomeEntity { get; set; }
}
Codes related with Test
[Fact]
public void Test1()
{
var data = new List<SomeEntity>() { new SomeEntity() { Id = 1, Name = "N1" }, new SomeEntity() { Id = 2, Name = "N2" } }.AsQueryable();
var fakeDbSet = A.Fake<DbSet<SomeEntity>>(x=>
{
x.Implements(typeof(IQueryable<SomeEntity>));
x.Implements(typeof(IEnumerable<SomeEntity>));
});
A.CallTo(() => ((IQueryable<SomeEntity>)fakeDbSet).GetEnumerator()).Returns(data.GetEnumerator());
var fakecontext = A.Fake<WebApplication6Context>(x =>
{
x.WithArgumentsForConstructor(new object[] { new DbContextOptionsBuilder<WebApplication6Context>().Options });
});
A.CallTo(() => fakecontext.SomeEntity).Returns(fakeDbSet);
var controller = new SomeEntitiesController(fakecontext);
//Act
var result=controller.GetEntities();
//Assert
Assert.Equal(2,result.Count);
}
The Result:
Upvotes: 1