Sharing services across test classes in MSTest - integration-testing

I'm working on a significant number of integration tests in MSTest (100+ for a subsystem), and I really want to group related tests into their own test classes, for readability and because different test groups require different configuration setup.
The tests originally started out with one big test class, that contained static instances of certain services. These services take a while to spin up, and will dominate the test execution time if they are brought up and torn down for each test. The original test code started like this.
[TestClass]
public class IntegrationTests
{
static ServiceA serviceA = new ServiceA();
static ServiceB serviceB = new ServiceB();
[ClassInitialize]
public static void ClassInit(TestContext context)
{
/* Gets the services up and going */
}
[TestInitialize]
public void TestInit()
{
/* Gets services back into good states */
}
/* Lots and lots of Integration tests */
[ClassCleanup]
public static void ClassCleanup()
{
/* Tear down the services */
}
}
The problem with this is different test groups need the services put into different states before the tests are run.
My first idea was to keep the static services in a common base test class, and then create new test classes that inherit from the base class for each test group, like this:
[TestClass]
public class TestClassA : IntegrationTests
{
/* tests */
}
[TestClass]
public class TestClassB : IntegrationTests
{
/* tests */
}
[TestClass]
public class TestClassC : IntegrationTests
{
/* tests */
}
The problem with that is the services get spun up and torn down for each test class. Granted, that's not as bad as them getting created and destroyed for each individual test, but I would like to create them once for each test run.
Is there a way to have separate test classes that all share the same services for integration testing in MSTest?

If I understand your question correctly, you can implement these services using a separate singleton. Something like:
public class Services
{
static ServiceA _serviceA
static ServiceB _serviceB
public static ServiceA InstanceA
{
if (_serviceA == null)
_serviceA = new ServiceA();
return _serviceA;
}
public static ServiceB InstanceB
{
if (_serviceB == null)
_serviceB = new ServiceB();
return _serviceB;
}
}
Then this class can be shared by all your test classes.

IProgrammer's answer will work, but here's the solution I came up with.
I added a static constructor the the base test class where all of the services are spun up, like so:
[TestClass]
public class IntegrationTests
{
static ServiceA serviceA = new ServiceA();
static ServiceB serviceB = new ServiceB();
//Static constructor gets called once during the lifetime of the appdomain.
static IntegrationTests()
{
/* Gets the services up and going */
}
[TestInitialize]
public void TestInit()
{
/* Gets services back into good states */
}
/* Lots and lots of Integration tests */
}
Cleaning up the resources after all the tests ran was a little more tricky, since C# does not have static destructors.
However, this answer provided a rather clean and clever workaround.
Here is the "static" destructor code.
private static readonly Destructor Finalise = new Destructor();
private sealed class Destructor
{
~Destructor()
{
/* Service cleanup code here */
}
}

Related

Unit of work pattern not allowing me to create db context without options

I am using ef core and I am trying to implement the repository pattern as part of best practices. But I am we bit confused on the context normally I would create the context in the and inject
HomeController(WarehouseDBContext _context)
I have created my unitOfWork Class as suggested by the docs here
https://learn.microsoft.com/en-us/aspnet/mvc/overview/older-versions/getting-started-with-ef-5-using-mvc-4/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application#creating-the-unit-of-work-class
However I am tad confused. It's expecting options here which is normally handled on the controller.
My UnitOfWork class
public class WarehouseUnitOfWork : IDisposable
{
private WarehouseDBContext context = new WarehouseDBContext();
private WarehouseRepository<StockItem> stockRepository;
public WarehouseRepository<StockItem> StockRepoistry
{
get
{
if (this.stockRepository == null)
{
this.stockRepository = new WarehouseRepository<StockItem>(context);
}
return stockRepository;
}
}
public void Save()
{
context.SaveChanges();
}
private bool disposed = false;
protected virtual void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing)
{
context.Dispose();
}
}
this.disposed = true;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
But here it is complain that it expect options which would I presume contain the connection string. I am trying to decouple my code from EF so that If I want to upgrade in the future will be easier. My WareshouseDBContext is describe below
As you can see it is expecting options. What should I pass through here?
namespace WareHouseDal.Dal {
public class WarehouseDBContext : IdentityDbContext<ApplicationUser> {
public WarehouseDBContext(DbContextOptions<WarehouseDBContext> options)
: base(options) {
}
public DbSet<WarehouseCrm> Warehouse { get; set; }
public DbSet<Company> Companies { get; set; }
}
}
When I used to create my context before I just used the singleton pattern of
private readonly WarehouseDBContext _context;
Is their something else I need to do to allow it to accept the creation of the context on the unit of work level.
Error being given is
You shouldn't create a DbContext manually. Why not injecting the DbContext in your UOW class? Then the DI will manage the life cycle of the db context. To be honest I am not a fan of adding a UOW wrapper around EF which already implements the UOW pattern.
I would recommend you to see both talks, it will change the way you structure apps forever:
https://www.youtube.com/watch?v=5OtUm1BLmG0&ab_channel=NDCConferences
https://www.youtube.com/watch?v=5kOzZz2vj2o&t=3s&ab_channel=NDCConferences
Another amazing talk about EF Core details: https://www.youtube.com/watch?v=zySHbwl5IeU&ab_channel=NDCConferences
If you want to stick with Repository pattern, please check Ardalis repository with a clear example: https://github.com/ardalis/CleanArchitecture
I agree Ardalis repository is a great tutorial/example, in case if anyone want a lite solution to implement the Repository and Unit of Work Patterns in EF 5/EF 6.
you may check out the below one, I tested it would work in EF Core 6
https://pradeepl.com/blog/repository-and-unit-of-work-pattern-asp-net-core-3-1/

Asp.net core, basic problems i dont understand

First Problem:
services.AddMemoryCache(); // in Startup config
public class AController
{
public AController(IMemoryCache cacheA) { }
}
public class BController
{
public BController(IMemoryCache cacheB) { }
}
problem is that cacheA is the same as cacheB
i'd like to have private API (cluster connections) and public API (exposed to frontend)
how to separate them while keeping it all DI pattern friendly?
Second problem;
i want to have a service that requests some external webserver via HTTP
and its results would be cached in that service, also stored in DB
so we first query localCache then query DB then query external server
results from that service would be used in Controllers and sent to frontend
How to implement such thing with all the fancy asp.netcore patterns?
cache must be the ONE(singleton) so we dont waste DB requests
? adding such Service as services.SCOPED<> but then how to keep it its cache same for every instance (some singleton DI? or static MemoryCache instance?)
i have no idea, no damn idea begging for help
in node.js i would have done it all in a couple of minutes, but its Microsoft hey
Define two cache interfaces:
public interface IPrivateMemoryCache: IMemoryCache
{
}
public interface IPublicMemoryCache: IMemoryCache
{
}
public class AController
{
public AController(IPrivateMemoryCache cacheA) { }
}
public class BController
{
public BController(IPublicMemoryCache cacheB) { }
}
Now you can define different instantiation rules for your IoC container.

How to organize a project into three tiers?

I have an asp.net website and I would like to organize it into three layers
DataAccess
Domain
UI
What specifically goes in each of these layers?
e.g
Data
- Models
- Repositories? Would that be just interfaces
- IoC?
Domain
- Services?
UI
- javascript
- Area specific models?
- css
Could someone provide a simple guideline for organizing an asp.net website like this?
As other people have said each situation is different, but for a basic architecture, I would probably go along with something like this. It has gotten me out of a few jams and up and running quite quickly.
Infrastructure Layer
This is where all the data access is done. Database connection management, etc.
The Repositories include all queries to the database.
The Dependency Resolution sits here too. Use your DI Container of choice.
Domain Layer
This is where all you business logic sits.
The Domain Services Interfaces are what the UI layer call to use your business logic
UI
Pretty obvious this one....
Code Example
--UI
public class MyController
{
private readonly IMySerivce _myService;
public MyController(IMySerivce myService)
{
_mySerivce = myService;
}
public void MyAction()
{
_myService.DoSomeAction();
}
}
--Domain
public Interface IMyService()
{
void DoSomeAction();
}
public class MySerivce : IMyService()
{
private readonly IMyRepository _myRespository;
public MySerivce(IMyRepository myRepository)
{
_myRepository = myRepository;
}
public void DoSomeAction()
{
_myRepository.Save();
}
}
public interface IMyRepository
{
void Save();
}
--DataLayer
public MyRepository : IMyRepository
{
public void Save()
{
//Manage Save here
}
}
Additionally I usually have a separate area for unit/integration tests.
Update
This most definitely is dependent on your situation. It is very hard to say what method is best without fully understanding what you are ultimately trying to build.
From the list below you can see which method works well for you or fits well with your architecture.
Regardless of which one you choose, your Repository Implementation will have to have a dependency on your Domain Objects project.
Some techniques in doing it include:
No Mapping
Your Domain Objects really then become dummy mappings to your tables. i.e. have a table in your database call User. Then have a Domain Object called User. This is by far the simplest technique.
--Domain
public class User
{
public int Id {get; set;}
public string UserName {get; set;}
public string FirstName {get; set;}
public string LastName {get; set;}
public string Password {get; set;}
}
--Infrastructure
public class UserRepository : IUserRepository
{
public Core.User GetById(int id)
{
return DBConnection.GetByIdQuery(id);
}
}
Mapping
Martin Fowler describes it here
It is possible in your infrastructure layer to have what are known as Domain Transfer Objects (DTO) that represent your database tables. Similar to above, a table called User, a DTO called User. Both having the same properties.
Your domain Entity then becomes a true representation of your domain and business logic.
The mapping of the DTO to your Domain Entity (search query) can be done in the Repository and the mapping of your Domain Entity to your DTO (save/update query) would also be done in your Repository.
To do your mapping you can either create custom mapping classes or use 3rd party tools like AutoMapper. I am a big fan of AutoMapper.
A sample code example would be along the lines of:
--Custom mapper
public class UserRepository : IUserRepository
{
private readonly IUserMapper _userMapper;
public UserRepository(IUserMapper userMapper)
{
_userMapper = userMapper;
}
public Domain.User GetUserById(int id)
{
var DtoUser = GetUserByIdQuery(int id);
return _userMapper.MapUserDTOToDomainEntity(DtoUser);
}
}
public class UserMapper : IUserMapper
{
public Domain.User MapUserDTOToDomainEntity(DataEntity.User dtoUser)
{
//Manual property mapping
}
}
--AutoMapper Example
public class UserRepository : IUserRepository
{
public Domain.User GetUserById(int id)
{
var DtoUser = GetUserByIdQuery(int id);
return Mapper.Map<Domain.User>(DtoUser);
}
}
Other examples include:
https://stackoverflow.com/questions/14724612
There are many many debates out there in blogs and here on SO about the value of DTO's,
including MSDN, this blog and these https://stackoverflow.com/questions/11237946, https://stackoverflow.com/questions/15148866

Proper way of using Unit of Work with unity injection

I am using unity, entity framework 4 with POCO classes, repository pattern for DAL and services for Business Logic control.
I also want to use Unit of Work so I can package together CRUD operations which I perform on different services and then commit them all together.
My question is what would be the proper way to inject the Unit Of Work mechanism into my application using Microsoft Unity?
I understand that I can put the IUnitOfWork together with the repository on the constructor of the proper service and then if Unity mapping is specified it would auto initiate the proper instances, but this way I do not pass the global unit of work but rather create a new instance on each level, which can't be a smart way to do it (actually the repository is initiated even before the service).
What am I missing? (Attached is constructor code as I wrote it now of service and its repository).
U also understand that I can use Unity's ParameterOverrides method to take some global instance of Unit of Work (lets say from my aspx.cs file) and pass it into the service and then into the repository. But it seems a bit lame. Is this my only option?
Thanks
public class GenericRepository<T> : IUnitOfWorkRepository, IGenericRepository<T> where T : BaseEntity, IAggregateRoot
{
private IUnitOfWork _uow;
/// <summary>
/// Returns the active object context
/// </summary>
private ObjectContext ObjectContext
{
get
{
return ObjectContextManager.GetObjectContext();
}
}
public GenericRepository(IUnitOfWork uow)
{
_uow = uow;
}
//blahhhh...
public void Add(T entity)
{
_uow.RegisterNew(entity, this);
}
public void Delete(T entity)
{
_uow.RegisterRemoved(entity, this);
}
//.....blah blah....
public void PersistCreationOf(IAggregateRoot entity)
{
this.ObjectContext.AddObject(GetEntitySetName(), entity);
}
public void PersistUpdateOf(IAggregateRoot entity)
{
// Do nothing as EF tracks changes
}
public void PersistDeletionOf(IAggregateRoot entity)
{
this.ObjectContext.DeleteObject(entity);
}
}
public class CategoryRepository : GenericRepository<XComSolutions.FB.Domain.Model.Entities.Category>, ICategoryRepository
{
public CategoryRepository(IUnitOfWork uow)
: base(uow)
{ }
}
public class CategoryService : ICategoryService
{
public int myID {get; set;}
private ICategoryRepository _categoryRepository;
private IUnitOfWork _uow;
public CategoryService(ICategoryRepository categoryRepository,
IUnitOfWork uow)
{
_categoryRepository = categoryRepository;
_uow = uow;
}
public List<Category> GetAll()
{
return _categoryRepository.GetAll();
}
}
Define an IUnitOfWorkFactory and inject that in your services:
public class Service
{
private readonly IUnitOfWorkFactory factory;
public Service(IUnitOfWorkFactory factory)
{
this.factory = factory;
}
public void DoOperation()
{
using (UnitOfWork context = this.factory.CreateNew())
{
this.DoSomeStuff(context);
this.DoMoreStuff(context);
context.SubmitChanges();
}
}
}
What I think you need to do is to define unit of work factory. You register this factory with your DI container and you resolve for this factory every time you need your unit of work. Then you get unit of work from the factory, work with it and let it go. You often will see that you need your unit of work within a scope of single method or single class. This article discuss Unit of Work pattern in connection with Entity Framework: http://msdn.microsoft.com/en-us/magazine/dd882510.aspx

Testable design

I have a java class which has a static member created using Facade (Singleton).
Class A implements InterfaceA {
private static DataStore db = DataStoreFacade.getInstance("BDB"); //singleton instance
public void save(final String key, final String val) {
db.save(key,val);
}
};
Here Class A is used as a member variable for webservice (stateless bean).
I can't test this code using EasyMock because there is no way to override the DataStore instance.
There are two options.
Have a constructor taking the instance of DataStore which will set to db member variable. The problem is I don't want webservice class to know which datastore instance has been created.
Provide an additional protected Set Method to override the db object. This is what I have used where I create a Easy Mock object of DataStore and override the member variable. Is it the correct design.
What are the other possibilities?
You're right that is bad for testability. Use dependency injection and don't go for static variable:
public class A implements InterfaceA {
private DataStore db;
public A(DataStore db) {
this.db = db;
}
...
}
to inject or build either use dependency-injection framework (e.g. spring) or build the object somewhere in bootstrap factory code yourself.
production code:
new A(DataStoreFacade.getInstance("...");
test-code:
public void test_xxx(){
DataStore db = EasyMock.createMock(DataStore.class);
//... do some expectations and replay(db)
InterfaceA a=new A(db);
//...
}
Well, the original code is already testable. Here is a unit test for it, using JMockit:
#Test
public void testSave(final DataStore mockDb)
{
final String key = "aKey";
final String value = "aValue";
new A().save(aKey, aValue);
new Verifications()
{{
mockDb.save(key, value);
}};
}
If needed, the DataStoreFacade class could be mocked too.
Why not make the db member protected, and in your test project inherit it and override that member:
project
{
Class A
{
protected static db = ...
public void Save(...) { ... }
}
}
test_project
{
Class B : A
{
protected override static db = ... (create test db)
}
Class testB
{
public A a;
public void Setup()
{
this.a = new B();
}
public void TearDown()
{
// delete a
}
public void TestSaveKey()
{
// test a
}
}
}
It's still hidden from consumers of the code/library, the test object isn't cluttering the production code, and the behaviour will be tested as if it were the production version.
Beware though, that having a static member for your db object could cause troubles for your tests if it's not cleaned up properly after each test.*
I know that you probably already know this, but I'm saying it for completeness.
Use the Supersede Instance pattern...
http://goodcoffeegoodcode.blogspot.com/2010/01/supercede-instance-pattern.html

Resources