I have a base context class that is derived from DbContext:
public abstract class BaseContext : DbContext
{
static BaseContext()
{
}
protected BaseContext()
: base("name=FrameworkOneDatabase")
{ }
}
Then some bounded contexts. Below is one of them: public class ArticleBoundContext : BaseContext
{
public ArticleBoundContext()
{
}
public virtual DbSet<Article> Article { get; set; }
public virtual DbSet<User> Submitter { get; set; }
}
Also a basic service class to help me calling CRUD operations on any bounded context: public class CRUDService
{
private BaseContext _context;
public CRUDService(BaseContext context)
{
this._context = context;
}
public void Insert(dynamic entityObject)
{
dynamic dbset = GetDbSetFromObject(entityObject);
entityObject.ObjectState = ObjectState.Added;
dbset.Add(entityObject);
_context.ApplyStateChanges();
}
public void InsertOrUpdate(dynamic entityObject)
{
dynamic dbset = GetDbSetFromObject(entityObject);
dbset.Attach(entityObject);
_context.ApplyStateChanges();
}
public void Delete(dynamic entityObject)
{
dynamic dbset = GetDbSetFromObject(entityObject);
dbset.Remove(entityObject);
}
public async Task<int> Commit()
{
var result = await _context.SaveChangesAsync();
return result;
}
public void Dispose()
{
_context.Dispose();
}
private dynamic GetDbSetFromObject(dynamic entityObject)
{
// if dynamicproxies wrapper is used then get the base object
System.Type objectType = entityObject.GetType();
if (objectType.Namespace == "System.Data.Entity.DynamicProxies")
{
objectType = objectType.BaseType;
}
var dbset = (from p in _context.GetType().GetProperties()
where p.PropertyType.IsGenericType
&& p.PropertyType.GetGenericTypeDefinition() == typeof(DbSet<>)
let entityType = p.PropertyType.GetGenericArguments().First()
where objectType == entityType
select p.GetValue(_context)).FirstOrDefault();
if (dbset == null)
{
throw new System.ArgumentException("object type does not exist in the context");
}
return dbset;
}
}
The class has methods accepting an object then will find its corresponding DbSetThen I can use all of the classes and structure above to do something like in the tests below:
[TestClass]
public class CRUDServiceTest
{
private ArticleBoundContext _context;
private CRUDService _service;
public CRUDServiceTest()
{
_context = new ArticleBoundContext();
_service = new CRUDService(_context);
}
[TestMethod]
public async Task CanInsertArticle()
{
Article article = new Article { Title = "title test " + DateTime.Now.ToString("HH:mm:ss"), Description = "desc", Url = "test.com", ObjectState = ObjectState.Added };
article.Submitter = new User { Firstname = "first " + DateTime.Now.ToString("HH:mm:ss"), Lastname = "last", ObjectState = ObjectState.Added };
_service.Insert(article);
var insert = await _service.Commit();
Assert.IsTrue(insert > 0);
}
[TestMethod]
public async Task CanUpdateArticle()
{
Article article = _context.Article.FirstOrDefault();
article.Title = "UPDATED TITLE " + DateTime.Now.ToString("HH:mm:ss");
article.Description = "UPDATED DESCRIPTION";
article.ObjectState = ObjectState.Modified;
_service.InsertOrUpdate(article);
var update = await _service.Commit();
Assert.IsTrue(update > 0);
}
[TestMethod]
public async Task CanUpdateSubmitter()
{
var article = _context.Article.FirstOrDefault();
article.Submitter.Firstname = "UPDATED FIRSTNAME " + DateTime.Now.ToString("HH:mm:ss");
article.Submitter.Lastname = "UPDATED LASTNAME " + DateTime.Now.ToString("HH:mm:ss");
article.Submitter.ObjectState = ObjectState.Modified;
_service.InsertOrUpdate(article);
var update = await _service.Commit();
Assert.IsTrue(update > 0);
}
[TestMethod]
public async Task CanUpdateSubmitter_2()
{
var submitter = _context.Submitter.FirstOrDefault();
submitter.Firstname = "UPDATED FIRSTNAME " + DateTime.Now.ToString("HH:mm:ss");
submitter.Lastname = "UPDATED LASTNAME " + DateTime.Now.ToString("HH:mm:ss");
submitter.ObjectState = ObjectState.Modified;
_service.InsertOrUpdate(submitter);
var update = await _service.Commit();
Assert.IsTrue(update > 0);
}
[TestMethod]
public async Task CanDeleteArticle()
{
var article = _context.Article.FirstOrDefault();
_service.Delete(article);
var result = await _service.Commit();
Assert.IsTrue(result > 0);
}
[TestMethod]
public async Task CanInsertAndDeleteSubmitter()
{
var submitter = new User();
submitter.Firstname = "firstname " +DateTime.Now.ToString("HH:mm:ss");
submitter.Lastname = "lastname " + DateTime.Now.ToString("HH:mm:ss");
_service.Insert(submitter);
var result = await _service.Commit();
Assert.IsTrue(result > 0);
var insertedSubmitter = await _context.Submitter.FindAsync(submitter.Id);
Assert.IsTrue(insertedSubmitter.Firstname == submitter.Firstname && insertedSubmitter.Lastname == submitter.Lastname);
_service.Delete(submitter);
result = await _service.Commit();
Assert.IsTrue(result > 0);
}
[TestMethod]
public async Task ThrowExceptionWhenInsertingWrongObject()
{
try
{
int test = 5;
_service.Insert(test);
var insert = await _service.Commit();
}
catch (Exception ex)
{
Assert.IsInstanceOfType(ex, typeof(System.ArgumentException));
}
}
}

No comments:
Post a Comment