Mock EF6 DBContext

3 posts, 1 answers
  1. Josh
    Josh avatar
    2 posts
    Member since:
    May 2015

    Posted 04 Oct 2015 Link to this post

    Downloaded the trial of JustMock since so many of the problems I have been facing are supposed to be addressable with it. I'm attempting to Mock an EF 6.1.3 DBContext. I have can build a test that runs directly against the DB and it works fine, but when I run against the Mocked Context I get an exception.

     To be clear I am using JustMock version 2015.3.929.5 also per the documentation I downloaded JustMock.EntityFramework from Nuget version 1.0.1. The Nuget installed incorrectly into the project and tried to explicitly target JustMock 2014.1.1424.1, but I corrected the config file back to the currently referenced version as mentioned above.

    Here is my code.

    public class Account
    {
     public int Id { get; set; }
     [Required]
     public string ExternalId { get; set; }
     public string AccountTimeZone { get; set; }
     public string FipsCode { get; set; }
     public bool DVREnabled { get; set; }
     public bool Enabled { get; set; }
     public double CreditLimit { get; set; }
     public int SdStreams { get; set; }
     public int HdStreams { get; set; }
     [Column(TypeName="DateTime2")]
     public DateTime CreatedTimeUTC { get; set; }
     [Column(TypeName = "DateTime2")]
     public DateTime LastUpdateTimeUTC { get; set; }
     public string CreatedBy { get; set; }
     public string UpdatedBy { get; set; }
     public AccountStatus AccountStatus { get; set; }
     public List<Device> Devices { get; set; }
     public List<SubscriberGroup> SubscriberGroups { get; set; }
     public List<AccountValue> AccountValues { get; set; }
     public SubscriberInfo SubscriberInfo { get; set; }
     public Device RecordingDevice { get; set; }
     [Required]
     public Tenant Tenant { get; set; }
     public List<Phone> Phones { get; set; }
     public List<AccountHistory> AccountHistory { get; set; }
    }

     

     

    public class Tenant
    {
     public int Id { get; set; }
     public string TenantName { get; set; }
     public string TenantDescription { get; set; }
     public string MediaroomVersion { get; set; }
     public TenantConfiguration TenantConfiguration { get; set; }
     public List<Account> Accounts { get; set; }
     public List<Device> Devices { get; set; }
     public List<ChangeEvent> ChangeEvents { get; set; }
    }

     

    public class EmptyAccount
    {
        public void CreateEmptyAccountInConductor(Account newAccount, int tenantId, string requestedBy, UnitOfWork uow)
        {
        var tr = new TenantRepository(uow);
        var tenant = tr.Find(tenantId);
        tenant.Accounts.Add(new Account(){ExternalId = newAccount.ExternalId, CreatedBy = requestedBy});
     
        tr.InsertOrUpdate(tenant);
        uow.Save();           
        }
    }

     

    public class TenantRepository : ITenantRepository
    {
        private readonly ConductorContext _context;
     
        public TenantRepository(UnitOfWork uow)
        {
            _context = uow.Context;
        }
     
        public Tenant Find(int id)
        {
            return _context.Tenants.Find(id);
        }
     
        public void InsertOrUpdate(Tenant entity)
        {
            if (entity.Id == default(int))
            {
                _context.Entry(entity).State = EntityState.Added;
            }
            else
            {
            _context.Entry(entity).State = EntityState.Modified;
            }
        }
    }

     

    public class ConductorContext : DbContext
    {
        public ConductorContext()
        {
            base.Configuration.ProxyCreationEnabled = false;
        }
     
        public DbSet<Account> Accounts { get; set; }
        public DbSet<AccountHistory> AccountHistories { get; set; }
        public DbSet<AccountTemplate> AccountTemplates { get; set; }
        public DbSet<AccountValue> AccountValues { get; set; }
        public DbSet<ChangeEvent> ChangeEvents { get; set; }
        public DbSet<Device> Devices { get; set; }
        public DbSet<DeviceValue> DeviceValues { get; set; }
        public DbSet<Phone> Phones { get; set; }
        public DbSet<SubscriberGroup> SubscriberGroups { get; set; }
        public DbSet<SubscriberInfo> SubscribersInfo { get; set; }
        public DbSet<Tenant> Tenants { get; set; }
        public DbSet<TenantConfiguration> TenantConfigurations { get; set; }
    }

      

    public class UnitOfWork : IUnitOfWork<ConductorContext>
    {
        private readonly ConductorContext _context;
     
        public UnitOfWork()
        {
            _context = new ConductorContext();
        }
     
        public UnitOfWork(ConductorContext context)
        {
            _context = context;
        }
     
     
        public int Save()
        {
            return _context.SaveChanges();
        }
     
     
        public void Dispose()
        {
            _context.Dispose();
        }
     
        public ConductorContext Context
        {
            get { return _context; }
        }
    }

     

     Direct to DB test that works.

    [Test]
    public void CreateEmptyAccountInConductor4()
    {
        // Arrange
        Database.SetInitializer(new DropCreateDatabaseAlways<ConductorContext>());
        var ctx = new ConductorContext();
        var fixture = new Fixture();
     
        var account = fixture.Build<Account>()
        .Without(p => p.Id)
        .Without(p => p.Tenant)
        .Without(p => p.AccountHistory)
        .Without(p => p.AccountValues)
        .Without(p => p.Devices)
        .Without(p => p.Phones)
        .Without(p => p.SubscriberGroups)
        .Without(p => p.SubscriberInfo)
        .Without(p => p.RecordingDevice)
        .Without(p => p.CreatedTimeUTC)
        .Without(p => p.LastUpdateTimeUTC)
        .Create();
     
        var tenant = fixture.Build<Tenant>()
        .With(p => p.Id, 1)
        .With(p => p.MediaroomVersion, "V2")
        .Without(p => p.Accounts)
        .Without(p => p.Devices)
        .Without(p => p.ChangeEvents)
        .With(p => p.TenantConfiguration, new TenantConfiguration())
        .Create();
     
        ctx.Tenants.Add(tenant);
        ctx.SaveChanges(); 
     
        // Act
        var sut = new EmptyAccount();
     
        sut.CreateEmptyAccountInConductor(account, 1, fixture.Create<string>(), new UnitOfWork(ctx));
     
        ctx.Dispose();
     
        // Assert
        ctx = new ConductorContext();
        // Force entity to load into context.
        var tenantAfter = ctx.Tenants.Find(1);
        var accountAfter = ctx.Accounts.Find(1);
        Assert.AreEqual(account.ExternalId, ctx.Tenants.Find(1).Accounts.Single(p => p.ExternalId == account.ExternalId).ExternalId);
    }

     

    Mocked Context that fails with a NullReferanceException in the InsertOrUpdate method of TenantRepository.

    [Test]
    public void CreateEmptyAccountInConductor3()
    {
        // Arrange
        var ctx = Mock.Create<ConductorContext>().PrepareMock();
     
        var fixture = new Fixture();
     
        var account = fixture.Build<Account>()
        .Without(p => p.Id)
        .Without(p => p.Tenant)
        .Without(p => p.AccountHistory)
        .Without(p => p.AccountValues)
        .Without(p => p.Devices)
        .Without(p => p.Phones)
        .Without(p => p.SubscriberGroups)
        .Without(p => p.SubscriberInfo)
        .Without(p => p.RecordingDevice)
        .Without(p => p.CreatedTimeUTC)
        .Without(p => p.LastUpdateTimeUTC)
        .Create();
     
        var tenant = fixture.Build<Tenant>()
        .With(p => p.Id, 1)
        .With(p => p.MediaroomVersion, "V2")
        .With(p => p.Accounts, new List<Account>())
        .Without(p => p.Devices)
        .Without(p => p.ChangeEvents)
        .With(p => p.TenantConfiguration, new TenantConfiguration())
        .Create();
     
        var tenantList = new List<Tenant>()
        {
        tenant
        };
     
        ctx.Tenants.Bind(tenantList);
     
        // Act
        var sut = new EmptyAccount();
        sut.CreateEmptyAccountInConductor(account, 1, fixture.Create<string>(), new UnitOfWork(ctx));
     
        // Assert
        Mock.Assert(() => ctx.SaveChanges(), Occurs.Once());
    }

     

    My assertion test for the Mocked Context is never even reached in the failing test. At this point I assume I'm doing something wrong. Any idea how I can get this to work because I don't want to be creating dropping my database over and over to run my test. This is just one of many I need to write like this.

     

     

     
  2. Answer
    Stefan
    Admin
    Stefan avatar
    198 posts

    Posted 06 Oct 2015 Link to this post

    Hello Josh,

    As I mentioned in your support ticket, your test is fine. The issue lies with the Resharper test runner, which, for some reason, decides not to let the JustMock profiler run.

    Regards,
    Stefan
    Telerik
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
  3. DevCraft R3 2016 release webinar banner
  4. Josh
    Josh avatar
    2 posts
    Member since:
    May 2015

    Posted 06 Oct 2015 in reply to Stefan Link to this post

    Appears to be user error on my part. For some reason during my testing of different scenarios I had disabled the profiler and forgot that it was off. Re-enabling it fixed the problem.

     

    Thanks.

Back to Top