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.