Does we need keep Business Logic Layer when we use CQRS + MediatR in net core? - repository-pattern

I use n-tier architecture in my net core applications and I want to apply cqrs + mediator patterns. But I have a question that our handlers should call business (service) layer or repository (data access) layer? Do I need to keep BLL or remove it?

No, you don't need to keep the BLL or DAL layer when you move to a CQRS + MediatR based architecture.
I recommend that you look into vertical slices architecture combined with CQRS/MediatR. See these videos:
Vertical Slice Architecture - Jimmy Bogard
Restructuring to a Vertical Slice Architecture
Think an important rule is that you should aim for is code that changes together should also be located together.

Related

Symfony2 best practice, business logic and unit test

I'd like to create a highly maintainable code, with unit tests.
I have read the best practices so directories are organized as per best practice, with just one bundle named AppBundle, and I'm using annotations.
I have an issue with business logic. I've read that I should not put business logic inside controllers. As the vast majority of my code was not meant to be reused I put the logic inside the controllers. Yesterday I read here that "logic should live in the controller unless you’re going to unit test it or until you need to re-use it" and this made me faint: am I not going to unit test if I put my logic inside controllers?
I understand that "controllers should be as lean as possible, with few lines of code to glue stuff together". But what about forms? A form often has a logic like "display the form, if it's valid do something and display another page". Now if I'm going to put the form creation and logic inside a service (or a model?) I'd have to put the page render command inside that, so basically the controller would be 1 line, with all the rest inside the service, and the actual decision of which page to display would be done inside the service, not the controller itself...so what's the point of a controller, just the routing?
I really need to understand this before proceeding (i've already developed 3 months on this and I'd have to rework a lot, but better now than never)...
Thank you!
EDIT: some additional considerations to address some of the comments below.
I have a clear understanding of how forms work in Symfony, with the creation of the form and it's management with the "isValid()" in the same place.
Let's imagine the following controller which performs the following operations:
get the current customer from security context
queries the DB to get the field $user->getIsBillable()
if the user is not billable
queries the DB to find if someone else is paying for him
else //the user is billable
create and manage form1
if the user is not billable but there is someone who is paying for him
check if the license is active (I have to call an external API)
if the license is not ok
redirect to a page to update credit card info
if the user is not billable
create and manage form2
else
create and manage form3
render the license management page with all the necessary forms created
What would be supposed to do? Put all this stuff into a service which would return the forms (or null if a form is not created)? Consider that in the "is valid" of some of the forms I render the same page with simply updated info. Or should I create a service foreach of the forms creation and keep the logic in the controller?
You should keep your logic outside the controllers in order for your code to be more reusable and to reduce code duplication.
The best practice is to have your business logic registered as a Symfony service instead.
The controller should be as lean as possible as it only handles the view and accessing your services to run business logic functionality.
Using services will make your code more reusable and it will be easier to write unit tests for each part of your code.
Forms are handled in a different way in Symfony2 and you should read more about it: http://symfony.com/doc/current/book/forms.html
Like most php frameworks, symfony2 has its problems.
Turns out symfony2 best practices are not always best practices. But in most cases symfony allows for loose coupling and proper dependency injection, it just doesn't tell you in the "book".
For example a very important topic: http://symfony.com/doc/current/cookbook/controller/service.html
I usually have my form types as services, my controllers as services and other services for the business logic. My controller actions are ideally around 3-5 lines of code. Sometimes when handling a file upload they will be slightly longer though.
You can unit test your business logic services, but for your controllers and forms you will need some sort of integration testing, or use heavy mocking.
I understand that "Selenium" is a good tool for testing such things, I haven't used it yet.
One thing that I would like add to other answers provided there to you is that Unit Test is different from Functional Test.
Unit Test
You need Unit Test when you want to test individual "unit" of code (such as method in a class)
Functional Test
You need Functional Test when you want to test a "suite" of functionalities (like many methods interactions, db interactions, web services and so on)
Recap
Ideally you want to write Unit Test(s) for a class that contains heavy business logic whereas you need Functional Test(s) for testing whole controller (so a page is render with all class interactions and db ones, the page is render, the page is posted and so on)
The best approach, to me - and it's only an opinion of a devel that tried as today to understand testing from a newbie point of view - is to mix each other: with Unit Test (and isolation, of course!) I'm sure that (simplifying) every input that I provide to my method will return the correct output, while functional test will help me to test the whole thing and interactions.
Answer
So, returning to your question - that seems wider that at first look could seems - a good way to procede is to keep all business logic outside controllers (even if you're sure [and to me you'll never be sure enaugh] that code you put in will be never reused elsewhere) by defining services (as said in other answers). Then you will do some unit test(s) onto your services and after that you will probably need some Functional Test(s) to check that all "the glue keep things together correctly".
I don't know if I'm missing something (it's likely). Just to be more complete, I will attach my older question on Symfony2 (I was studying it and MVC pattern at the time)
Structuring your code to be clean and maintainable it is a very hard stuff, I suggest you to start studying the SOLID principles than having a superficial understanding of MVC:
Single Responsability Principle - SRP
Open/Closed Principle - OCP
Liskov Substitution - LSP
Interface Segregation - ISP
Dependency Inversion Principle - DIP

Testing RESTful service, should I also check the data layer?

Testing the results of the endpoints is straight forward.
However, shouldn't I also have a look at the db layer, if (i.e.) the data I POSTed is saved correctly? I'm unclear how/if the business logic behind the REST call should be tested.
In my perfect world (someday I'd like to live there...) there are several different tests involved in fully validating a RESTful service I am providing.
There are unit tests for each of the logical layers of the application, that use dependency injection to mock the next lower layer and validate that each unit works correctly. This might be a unit that marshals/unmarshals the parameters and response, a unit that executes business logic, and a unit that manages persistence. (There could be multiple units, each with their own tests at each layer.) These tests have no dependencies outside the testing framework, with the exception of the persistence layer which has to exercise your persistence implementation.
There are also integration tests that require a running system. This is where you call the running service, and verify that you got the expected response. You may also inspect side effects of the call. On my team, we often do that by making a different service call (or calls) that relies on the result of the first call. That exercises more of the system. We find that direct inspection of the persistence layer for side effects seldom tells us much that we can't get by using a different service call.
Yes, you should test the db layer at some point but probably not in the same unit test than the one that test the result of the endpoint.
At the Unit Test level you would like to have small/quick/independant tests so you might end up with a test/suite for the REST part and another one focussing on db layer.
Then you might have some more integration/end-to-end tests that check the whole system : doing the request and checking the db is correctly updated.
My own experience, working as a QA, is that the tests involving DB are done with integration/end-to-end tests with a functional perspective by the QA using a third-party tool (we use Robot Framework for that).
One way of doing it is use the restful service itself to test that the data correctly persisted,
For example you can use the PUT message to persist an entity and use the GET operation to retrieve it, and make sure all properties are equal. This is more of an integration test which covers end to end.
Especially your application is doing more CRUD operations, and if you use this approach you could avoid creating tests for each and every layer (such as repositories)

What part of project to test first?

I want to write first unit test in my life.
At present, I am developing new ASP.NET MVC 5 project. This is simple workflow system. My project contains 4 layers:
Presentaton layer (an MVC-project)
Infrastructure layer (which contains Repositories and ORM)
Domain (which contains POCO classes and interfaces of busines logic)
Service layer (which is implemented domain interfaces)
I believe, that I need test Service layer firstly. Is that right? Which layer should I test first?
There's no single correct approach, but the most common techniques are
Top-Down, also called Outside-In. Here, you start at the outside layer and work your way in.
Bottom-Up. Here, you start with the constituent building blocks and assembly them to a working system.
As Code Complete describes, using dual approaches interchangeably can actually be beneficial, because the stuff you learn from doing one thing, helps you better understand what you need to do in the other end, and vice versa. I often do a bit of Outside-In, then some Bottom-Up, then some more Outside-In, etc.
As per Mark Seemann's answer, you can test from UI layer first and finish with the data layer, or in reverse.
Who is responsible for the project? Which part of the project is business critical? Rather than test across each layer "horizontally", test through all of the layers for a particular piece of functionality "vertically".
This gives you the benefit of coverage based on business priorities and you can apply any testability changes you need to make or techniques across all of the layers as you start to test each piece of functionality.
Since you have written your code already, be prepared to refactor some code to make it more testable (for example setting up Dependency Injection to isolate code for unit testing) and make note of these changes to help design for testability in future.

N-tier architecture to describe an Iphone application

I built a mobile application and one of the ways that i wanna explain it to people is by four-tier architecture; so after a little reading and research. From what i understood i did this design
looking at the communication between first two layers I'm not sure if i did it correctly. i think that i read somewhere that each tier have to be separated physically which obviously is not. but its satisfied that both layers can be built separately..right?
in the end is the diagram representing a four-tier architecture correctly. Thanks in advance
Yeah, that looks about right. The main iOS programming paradigm is model-view-controller (MVC), so you could add a controller tier in between presentation and business logic.
Tiers do not have to have a physical seperation so don't get too hung up on that.

UI testing vs unit testing

what is the different purpose of those both? I mean, in which condition I should do each of them?
as for the example condition. if you have the backend server and several front-end webs, which one you'll do?do-unit testing the backend server first or do-UI testing in the web UI first?
given the condition, the server and the front-end webs already exist, so it's not an iterative design to build along with (TDD)...
Unit testing aims to test small portions of your code (individual classes / methods) in isolation from the rest of the world.
UI testing may be a different name for system / functional / acceptance testing, where you test the whole system together to ensure it does what it is supposed to do under real life circumstances. (Unless by UI testing you mean usability / look & feel etc. testing, which is typically constrained to details on the UI.)
You need both of these in most of projects, but at different times: unit testing during development (ideally from the very beginning, TDD style), and UI testing somewhat later, once you actually have some complete end-to-end functionality to test.
If you already have the system running, but no tests, practically you have legacy code. Strive to get the best test coverage achievable with the least effort first, which means high level functional tests. Adding unit tests is needed too, but it takes much more effort and starts to pay back later.
Recommended reading: Working Effectively with Legacy Code.
Unit test should always be done. Unittests are there to provide proof that each UNIT (read: object) of your technical solution delivers the expected results. To put it very (maybe too) simple, user testing is there to verify that your system fulfills the needs and demands of the user.
Test pyramid [1] is important concept here, well described by Martin Fawler.
In short, tests that run end-to-end through the UI are: brittle and expensive to write. You may consider test recording tools [2] to speed recording and re-recording up. Disclaimer - I'm developer of such tool.
[1] https://martinfowler.com/articles/practical-test-pyramid.html
[2] https://anwendo.com
In addition to the accepted answer, today I just came up with this question of why not just programmatically trigger layout functions and then unit-test your logic around that as well?
The answer I got from a senior dev was: programmatically trigger layout functions will not be an absolute copy of the real user-experience. In the real world, the system will trigger many callbacks, like when the user of an app backgrounds or foregrounds the app. Obviously you can trigger such events manually and test again, but would you be sure you got all events in all sequences right?!
The real user-experience is one where user makes actual network calls, taps on screens, loads multiple screen on top of each other and at times you might get system callbacks. Callbacks which you forgot to mock that you didn't properly mock. In unit-tests you're mainly testing in isolation. In UI test, you setup the app, may have to login, etc. That stack you build is much more complex vs a unit-test. Hence it's better to not mix unit-testing with UI testing.