Base solution for your next web application
Open Closed

Unit Testing Domain Services #6201


User avatar
0
davidharrison created

Hi all,

I'm in the process of building out unit tests for the new functionality that we've added to our .net zero project. So far, for the app services, this is going swimmingly. However we have several pieces of functionality that sit in domain layer managers, and I'm struggling to implement unit tests for those.

My first question is, is there an ideal or proper way of implementing a unit test in .net zero for domain layer managers?

Where I've managed to get so far is creating an interface for the domain manager, which allows it to be resolvable in the unit test project. When running the test, it correctly creates an instance of the manager, but then fails due to a disposed object error on a repository. This isn't an issue when running a unit test on an app service that calls a method inside of a manager that uses a repository, but I'm not sure what the missing difference is between an app service unit test and a domain manager unit test.

If I'm on the right path with this approch, how does one correctly resolve a domain manager such that it correctly used the test context? (Which I guessing is what fails with the disposed object error)

Thanks,

David


4 Answer(s)
  • User Avatar
    0
    ryancyq created
    Support Team

    Hi @davidharrison , can you share the code of how you resolve those domain layer managers? Also, possible the Dispoaed Object exception stack trace as well.

  • User Avatar
    0
    davidharrison created

    Hi @ryancyq

    I added an interface for the folder manager (and converted the manager to implement the interface).

    using Syntaq.Falcon.AccessControlList;
    using Syntaq.Falcon.Folders.Dtos;
    using System.Threading.Tasks;
    
    namespace Syntaq.Falcon.Folders
    {
    public interface IFolderManager
    {
    Task CreateOrEditFolder(ACL ACL, Folder Folder);
    Task CreateAndOrFetchFolder(ACL ACL, Folder Folder);
    
    Task Move(MoveFolderDto moveFolderDto);
    
    }
    }
    

    And then I'm resolving the interface at the top of the unit test.

    public class FolderManager_Tests : AppTestBase
    {
    private readonly IFolderManager _folderManager;
    
        public FolderManager_Tests()
        {
            _folderManager = Resolve<IFolderManager>();
        }
    
    

    And here is the stack trace

    [27/12/2018 11:14:34 AM Informational] [xUnit.net 00:00:22.43] System.ObjectDisposedException : Cannot access a disposed object. A common cause of this error is disposing a context that was resolved from dependency injection and then later trying to use the same context instance elsewhere in your application. This may occur if you are calling Dispose() on the context, or wrapping the context in a using statement. If you are using dependency injection, you should let the dependency injection container take care of disposing context instances. [27/12/2018 11:14:34 AM Informational] [xUnit.net 00:00:22.43] Object name: 'FalconDbContext'. [27/12/2018 11:14:34 AM Informational] [xUnit.net 00:00:22.43] Stack Trace: [27/12/2018 11:14:34 AM Informational] [xUnit.net 00:00:22.43] at Microsoft.EntityFrameworkCore.DbContext.CheckDisposed() [27/12/2018 11:14:34 AM Informational] [xUnit.net 00:00:22.43] at Microsoft.EntityFrameworkCore.DbContext.get_DbContextDependencies() [27/12/2018 11:14:34 AM Informational] [xUnit.net 00:00:22.43] at Microsoft.EntityFrameworkCore.DbContext.get_Model() [27/12/2018 11:14:34 AM Informational] [xUnit.net 00:00:22.43] at Microsoft.EntityFrameworkCore.Internal.InternalDbSet'1.get_EntityType()
    \[27/12/2018 11:14:34 AM Informational\] \[xUnit\.net 00:00:22\.43\] at Microsoft\.EntityFrameworkCore\.Internal\.InternalDbSet'1.get_EntityQueryable() [27/12/2018 11:14:34 AM Informational] [xUnit.net 00:00:22.43] at Microsoft.EntityFrameworkCore.Internal.InternalDbSet'1.System.Linq.IQueryable.get_Provider()
    \[27/12/2018 11:14:34 AM Informational\] \[xUnit\.net 00:00:22\.43\] at System\.Linq\.Queryable\.Any\[TSource\]\(IQueryable'1 source, Expression'1 predicate)
    \[27/12/2018 11:14:34 AM Informational\] \[xUnit\.net 00:00:22\.43\] D:\Source\Syntaq\.Falcon\src\Syntaq\.Falcon\.Core\Folders\FolderManager\.cs\(92\,0\): at Syntaq\.Falcon\.Folders\.FolderManager\.CreateAndOrFetchFolder\(ACL ACL\, Folder Folder\)
    \[27/12/2018 11:14:34 AM Informational\] \[xUnit\.net 00:00:22\.43\] D:\Source\Syntaq\.Falcon\test\Syntaq\.Falcon\.Tests\Folders\FolderManager\_Tests\.cs\(29\,0\): at Syntaq\.Falcon\.Tests\.Folders\.FolderManager\_Tests\.Should\_Fetch\_Folder\(\)
    \[27/12/2018 11:14:34 AM Informational\] \[xUnit\.net 00:00:22\.43\] \-\-\- End of stack trace from previous location where exception was thrown \-\-\-\
    
  • User Avatar
    1
    alper created
    Support Team

    create your domain services like this

    public interface IFolderManager : IDomainService
    {
       //...
    }
    
    public class FolderManager : DomainService, IFolderManager
    {
       //...
    }
    

    https://aspnetboilerplate.com/Pages/Documents/Domain-Services#example

  • User Avatar
    0
    davidharrison created

    Thank you @Alper