Unit Testing CQRS Handlers With Moq, Fluent Assertions, and xUnit

  Рет қаралды 38,553

Milan Jovanović

Milan Jovanović

Күн бұрын

Пікірлер: 139
@MilanJovanovicTech
@MilanJovanovicTech 2 жыл бұрын
Want to master Clean Architecture? Go here: bit.ly/3PupkOJ Want to unlock Modular Monoliths? Go here: bit.ly/3SXlzSt
@kinggrizzly13
@kinggrizzly13 2 жыл бұрын
XUnit tests - check Testing internal classes - check Exactly what I was looking for. Thank you!!!
@MilanJovanovicTech
@MilanJovanovicTech 2 жыл бұрын
Awesome, glad I helped someone 😁😁
@MarcusKaseder
@MarcusKaseder 2 жыл бұрын
You can also write internals visible to with this shorthand:
@MilanJovanovicTech
@MilanJovanovicTech 2 жыл бұрын
Awesome, I didn't know that!
@sergiom.954
@sergiom.954 2 жыл бұрын
I didn't know about the internal visibility feature for test projects. Thanks Milan for your job.
@MilanJovanovicTech
@MilanJovanovicTech 2 жыл бұрын
You're welcome Sergio, glad you liked it 😁
@SajidAliSoftwareEngineer
@SajidAliSoftwareEngineer 2 жыл бұрын
yes Millan we need more unit testing videos. Thank you so much for such nice video.
@MilanJovanovicTech
@MilanJovanovicTech 2 жыл бұрын
I heard you loud and clear 😁
@SajidAliSoftwareEngineer
@SajidAliSoftwareEngineer 2 жыл бұрын
@@MilanJovanovicTech 😅
@martinbryant3515
@martinbryant3515 2 жыл бұрын
Hi Milan I think this is exactly how I would have approached this apart from one observation - really like the use of the Verify method when doing calls to other interfaces - try using Automock to setup mocks and then when you create your class use Automock Create method, the mocking will be done automatically using Dependency Injection - this helps when you grow out the class and add more dependencies saving you having to alter your previous tests. Great videos btw 😊
@MilanJovanovicTech
@MilanJovanovicTech 2 жыл бұрын
This is pretty cool! Growing list of dependencies is indeed a big pain. I have to explore Automock more now 😁
@BEARMC27
@BEARMC27 2 жыл бұрын
Great video! I don't code in C# anymore, switched to Kotlin, this video still give me some concept on what to do when unit testing CQRS related stuff.
@MilanJovanovicTech
@MilanJovanovicTech 2 жыл бұрын
Awesome, glad you liked it. I took a look at Kotlin once, and it seemed very similar to ASP .NET
@milicabozic9897
@milicabozic9897 2 жыл бұрын
Thank you, this will be very useful for my unit tests.
@MilanJovanovicTech
@MilanJovanovicTech 2 жыл бұрын
Awesome, Milica!
@jogadordejogos4041
@jogadordejogos4041 2 жыл бұрын
Hello Milan, I'm Brazilian and I've been following your content since the beginning and I think your teaching is very good. You don't think about creating a course or something?
@MilanJovanovicTech
@MilanJovanovicTech 2 жыл бұрын
Yes, I'm planning to release a course early next year :)
@ajaypanse4489
@ajaypanse4489 9 ай бұрын
Hi Milan, Your videos are very good. Can you share a video in which we can write unit test cases for repository classes, in this we will not hit to database but will execute CRUD functionality
@MilanJovanovicTech
@MilanJovanovicTech 9 ай бұрын
This could be helpful: kzbin.info/www/bejne/n5y1gZmlgNFkiac
@calblui
@calblui Жыл бұрын
Great job man! I'm learning a lot from your classes
@MilanJovanovicTech
@MilanJovanovicTech Жыл бұрын
Glad to hear it!
@ZeBobo5
@ZeBobo5 2 жыл бұрын
You can use this csproj itemgroup item :
@MilanJovanovicTech
@MilanJovanovicTech 2 жыл бұрын
Pretty cool, I wasn't aware of that
@Yash42189
@Yash42189 2 жыл бұрын
Hey man, thanks for the great video! I was wondering if you have a video/playlist where you are building the actualy application?
@MilanJovanovicTech
@MilanJovanovicTech 2 жыл бұрын
If you go back to the earliest videos, I start more or less from scratch
@woquendoG
@woquendoG Жыл бұрын
Hi nice video, I am wondering what's that Result generic class, I'm just learning unit testing and didn't see that in the course I took, do you have a video explaining what is that?
@MilanJovanovicTech
@MilanJovanovicTech Жыл бұрын
This one here: kzbin.info/www/bejne/gZjJq4Bmhrx7qLM
@dxs1971
@dxs1971 2 жыл бұрын
also you could fill repository with predefined email and than the test will have purpose
@MilanJovanovicTech
@MilanJovanovicTech 2 жыл бұрын
Perhaps, but not what I tried to do in this video
@ibrahimhebish1404
@ibrahimhebish1404 2 жыл бұрын
You did a great job Milan , it would be nice if we have a full series on testing
@MilanJovanovicTech
@MilanJovanovicTech 2 жыл бұрын
I'm surely going to make a few more videos!
@PaulSebastianM
@PaulSebastianM 2 жыл бұрын
But wouldn't you start writing the tests by first thinking about your handler signature? If you know you're going to write a handler and know its shape, you can deduce all test cases based on input (is the email valid, is it unique, do the first and last names need validation, what happens when they are not valid, etc.). So wouldn't you write your tests first, then write the handler in TDD fashion?
@MilanJovanovicTech
@MilanJovanovicTech 2 жыл бұрын
I don't practice TDD 🤷‍♂️ So it didn't make sense for me to start now. But I may try it for some video.
@benjaminvenezia1944
@benjaminvenezia1944 12 күн бұрын
Hi! Thank's for the great content! What is Result class you use to wrap Guid? Ty
@MilanJovanovicTech
@MilanJovanovicTech 12 күн бұрын
Something like this: gist.github.com/m-jovanovic/aa25b1ae424c985ff8ae696a79b6fe6e
@shuvbhowmickbestin
@shuvbhowmickbestin 2 ай бұрын
Hey Milan, I have one question. I see the IsFailure method of the Result class and can instantly recognize the pattern as my projects in work use a similar pattern for their code. I wanted to know if there was a framework that wrote all this boilerplate code (Result, IResult) class or are we creating all this code ourselves.
@MilanJovanovicTech
@MilanJovanovicTech 2 ай бұрын
I wrote it myself, as it's not a lot of code. But there are a bunch of NuGet packages you can use: kzbin.info/www/bejne/eWLSeKF6etOGZ5Y
@AboutCleanCode
@AboutCleanCode 2 жыл бұрын
I wonder whether 100% code coverage with unit tests is even desireable. In simple cases like this one it is certainly possible without any trouble but if the code gets slightly more complex that can be a quite challenging goal, esp. if we consider path coverage. An alternative would be "risk based testing". What is your opinion?
@MilanJovanovicTech
@MilanJovanovicTech 2 жыл бұрын
100% coverage should never be the goal by itself. The goal should be to write meaningful tests. And coverage will come on its own.
@Senboni
@Senboni 2 жыл бұрын
I love me some xunit + moq combination 👌
@MilanJovanovicTech
@MilanJovanovicTech 2 жыл бұрын
Awesome 🔥
@jorgegarcia8843
@jorgegarcia8843 Жыл бұрын
Great job! Can the Command Validator be tested in the Handler unit test? When I call the endpoint, I can only try Command Validator in integration tests.
@MilanJovanovicTech
@MilanJovanovicTech Жыл бұрын
No, but check out my Testcontainers video which runs the entire MediatR pipeline. Or you can unit test the command validator on its own.
@hamitkarahan2973
@hamitkarahan2973 2 жыл бұрын
Nice video Milan, thanks for good contents!
@MilanJovanovicTech
@MilanJovanovicTech 2 жыл бұрын
You're most welcome!
@shatvani
@shatvani Жыл бұрын
Hi Milan! What if I put repository setup into a different file and I want to add an entity to the list of the mocked repo and I wan to get this entity with a mocked get method? How could I give the parameters to the mocked get method, please? I thought I give them at the instantianation of the mocked repository or with a callback, I do not know.
@MilanJovanovicTech
@MilanJovanovicTech Жыл бұрын
With Moq, you can configure the Get method to return a list of your choosing
@vekzdran
@vekzdran 2 жыл бұрын
Great coverage, pun intened! :) I do exactly the same so nothing to add much. I was wondering, do you know if VSIDE or other tools visualize coverage in actual source after the test run. I had this experience with vacode in golang and was a fantastic experience to see actual source highligthed after test run and immediatelly you’d see the unhighlighted-not tested code. Any idea? Also would love to see you cover that + calculating code coverage with eg coverlet. Good work Milan.
@MilanJovanovicTech
@MilanJovanovicTech 2 жыл бұрын
I used dotCover for this, but it's a paid tool from Jetbrain. Well worth it to be honest.
@eliesamyoun1006
@eliesamyoun1006 Жыл бұрын
Hello Milan. Thank you so much for the wonderful videos. I am learning so much from these. I have one small question. When the test if the email is Unique, is the unit test actually inserting this member into the database? And if yes, how can we prevent it?
@MilanJovanovicTech
@MilanJovanovicTech Жыл бұрын
No - these are just unit tests. They don't touch the DB.
@arpanmukherjee4625
@arpanmukherjee4625 10 ай бұрын
The only issue being, what if I have another command sent from my command handler using the ISender / IMediator interface. That's a perfectly valid use of MediatR and CQRS, but how do you test it? Would that be a Unit Test technically if we don't mock the response from the other Command? Also, what if I actually want to test the entire flow together with the second Mediator command (even if that's called a Integration Test)?
@MilanJovanovicTech
@MilanJovanovicTech 10 ай бұрын
Testing the entire flow = write an integration test Otherwise, you can mock the response and run with it
@joasengelberts594
@joasengelberts594 2 жыл бұрын
Hi Milan, Great video, but I am missing one thing here, which is being able to mock the domain logic. Let's say I have a AcceptInvitationCommandHandler which gets a gathering from the repository and calls AcceptInvitation on it. I don't want to test the gathering's domain logic of the invitation being accepted and the attendee being added, I should have a separate domain unit test for that. However, I do want to validate the command handler has invoked AcceptInvitation properly. Do I have to create interfaces for every aggregate and have the repository return interfaces instead? Should my static factories return the interface aswell?
@MilanJovanovicTech
@MilanJovanovicTech 2 жыл бұрын
You shouldn't verify if it was invoked or not. You just need to verify the end result is what you expect it is. And test the Domain (AcceptInvitation in this case) in a separate test.
@erald_doka
@erald_doka 2 жыл бұрын
Hi Milan, What theme/colours are you using for the visual studio?
@MilanJovanovicTech
@MilanJovanovicTech 2 жыл бұрын
Hey! This is ReSharper dark theme
@jonaslewin
@jonaslewin 2 жыл бұрын
Please create more videos in your awesome Clean Architecture & DDD Series.
@MilanJovanovicTech
@MilanJovanovicTech 2 жыл бұрын
They're on the way!
@Cornet435
@Cornet435 Жыл бұрын
Very nice video ☺️ Will you ever make a video about integration tests?
@MilanJovanovicTech
@MilanJovanovicTech Жыл бұрын
At some point, definitely
@amirpeeri
@amirpeeri 2 жыл бұрын
Hey Milan. I was just about to start writing unit tests for a project so great timing 😀. A question though. why are you not validating the results of your value object creation, as they too can fail. Also, in a scenario like this where you create multiple value objects one after the other, how would you check the results? would you have an if statement after every one of them or is there a cleaner way you think? Thanks!
@MilanJovanovicTech
@MilanJovanovicTech 2 жыл бұрын
Fair point, I missed that kind of. But also video would be too long. I'll make a part 2! The idea is to add an extension method on Result, and validate all the results at the same time. We can return either first failure, or all failures.
@tarekhaydar9795
@tarekhaydar9795 2 жыл бұрын
Thank you Milan. I have a question please, do we need to have seperate unit tests for the domain project? Or the domain project should be tested in the context of the Application project?
@MilanJovanovicTech
@MilanJovanovicTech 2 жыл бұрын
Yes, for sure. For whatever reason I started from Application project 🤷‍♂️ I'll make sure to do a TDD style approach with Domain project soon.
@PelFox
@PelFox 2 жыл бұрын
You should have one unit test project per library you create. Integration tests can go through everything from the api endpoints.
@alexalexander3252
@alexalexander3252 Жыл бұрын
Dam maaaaan, your left eyebrow move made me like your video, and right eyebrow move made me subscribe. Your are hypnotizer ot what?
@MilanJovanovicTech
@MilanJovanovicTech Жыл бұрын
Rofl 🤣 It's a super power of mine!
@bojanpavlovic5038
@bojanpavlovic5038 2 жыл бұрын
Nicely done! I am working on a project that doesn't use repository but context injected in the handler. How would you approach testing this? What is your opinion?
@PelFox
@PelFox 2 жыл бұрын
Personally I'm a fan of integrationtesting handlers using WebApplicationFactory and TestContainers to spin up a docker container with a SQL database. But if you prefer to unit test handlers and they have a direct dependency on DbContext, the go-to would be using InMemoryProvider for the DbContext to mock it that way. Just a side note that unit testing the handlers won't trigger any PipelineBehaviors for the full MediatR request, an integrationtest would.
@MilanJovanovicTech
@MilanJovanovicTech 2 жыл бұрын
As @pelfox suggested, in-memory EF provider is a very good option for unit testing EF context. I wouldn't advise mocking EF, you're going to end up going down a deep rabbit hole.
@bojanpavlovic5038
@bojanpavlovic5038 2 жыл бұрын
Yeah. In memory done the job well actually. But was curious to hear your opinion! Thanks!
@MilanJovanovicTech
@MilanJovanovicTech 2 жыл бұрын
@@bojanpavlovic5038 I tried some sort of DbContext Mock once, but it really didn't scale. It requires a LOT of code to set up a test, not worth it.
@bojanpavlovic5038
@bojanpavlovic5038 2 жыл бұрын
I have made seed classes and a provider put all together and just load all in constructor. End up being very simple and easy
@y.5107
@y.5107 9 ай бұрын
How to test actions which simply execute dapper (CQRS) queries?
@MilanJovanovicTech
@MilanJovanovicTech 9 ай бұрын
Integration tests with Testcontainers
@y.5107
@y.5107 8 ай бұрын
@@MilanJovanovicTechso actually testing against the database? Seed the database and assert against the expected results?
@jarnohonkanen4321
@jarnohonkanen4321 2 жыл бұрын
This was almost identical way to do CQRS handler unit testing what i end up to do some time ago. I like to know more UnitOfWork and how to approach repository implementation when Domain entity model is not 100% identical what database is using because legacy reasons. Specially how to deal entity id's when it's not GUID but database generated int?
@MilanJovanovicTech
@MilanJovanovicTech 2 жыл бұрын
Unit of Work video is coming out on Friday! 😁 And I'll tackle Entity Id generation in a separate video
@SabbirHossain-el2rv
@SabbirHossain-el2rv 6 ай бұрын
I used ExecuteUpdateAsync method in one of my handle method, and it throws error during unit test. Is there any way we can test handler containing ExecuteUpdateAsync method.
@MilanJovanovicTech
@MilanJovanovicTech 6 ай бұрын
Use a proper DbContext
@murat.yuceer
@murat.yuceer 2 жыл бұрын
Hello Milan, Is there a repository where all the lessons you have done are collected?
@MilanJovanovicTech
@MilanJovanovicTech 2 жыл бұрын
At the moment, I only share the code with my Patreon supporters. On occasion, I will post something on my GitHub also.
@murat.yuceer
@murat.yuceer 2 жыл бұрын
@@MilanJovanovicTech you can post all things
@RichardONeil
@RichardONeil 2 жыл бұрын
This was great! Thanks!
@MilanJovanovicTech
@MilanJovanovicTech 2 жыл бұрын
Awesome. What's your approach?
@ifstatementifstatement2704
@ifstatementifstatement2704 2 жыл бұрын
Client: “why did the project take twice as long?” Dev: “unit testing”
@MilanJovanovicTech
@MilanJovanovicTech 2 жыл бұрын
They'll thank you later when you don't need to do bug fixing
@ifstatementifstatement2704
@ifstatementifstatement2704 2 жыл бұрын
@@MilanJovanovicTech I’m new to software engineering but not programming. I’ve always done unit testing but not by writing tests, but by running the code to test the new feature, with different initial states. I think writing official tests is a good thing for commercial projects but I don’t do it for personal projects I work on solo at home.
@godwindiaba9122
@godwindiaba9122 5 ай бұрын
Thank you very much sir
@MilanJovanovicTech
@MilanJovanovicTech 5 ай бұрын
You are welcome
@100kshooter5
@100kshooter5 2 жыл бұрын
This is an interesting topic really appreciate it. . .l would like us to get to how to launch 2 services that use docker in two containers but they use the same Application layer with just different entry points. . .which should be the benefit of the clean architecture, having multiple entry point and one code base, in two docker containers. . .one service could be the api and the other the outbox service for example.
@MilanJovanovicTech
@MilanJovanovicTech 2 жыл бұрын
Interesting idea. So basically two web apps, using the same projects underneath?
@100kshooter5
@100kshooter5 2 жыл бұрын
@@MilanJovanovicTech Yes, multiple entry points l would call them for example. One container runs the api. One container runs a CLI. Both can create commands using the same code base but are started in different containers/services as they are different entry points to the application. This can be extended to N entry points/services using one code base.
@MilanJovanovicTech
@MilanJovanovicTech 2 жыл бұрын
@@100kshooter5 Makes sense. I implemented something similar to that on my GitHub, check out the event-reminder repo And I'll work on a video
@100kshooter5
@100kshooter5 2 жыл бұрын
@@MilanJovanovicTech Amazing thank you. . .
@Zainjerr
@Zainjerr Жыл бұрын
This is awesome!
@MilanJovanovicTech
@MilanJovanovicTech Жыл бұрын
Thank you!
@JulianoLambda
@JulianoLambda 2 жыл бұрын
Why are you returning from repository Domain Entities and not Database Models? You set in the dbContext (UoW) Domains Entities. Why are you doing it?
@MilanJovanovicTech
@MilanJovanovicTech 2 жыл бұрын
Domain Entities are DB Entities also, that's why. I don't create separate models.
@onedev7316
@onedev7316 2 жыл бұрын
excellent. Have you got github link for above example?
@MilanJovanovicTech
@MilanJovanovicTech 2 жыл бұрын
Yes, but only for me Patreon supporters
@onedev7316
@onedev7316 2 жыл бұрын
@@MilanJovanovicTech Patreon link please.
@MilanJovanovicTech
@MilanJovanovicTech 2 жыл бұрын
@@onedev7316 www.patreon.com/milanjovanovic
@RavinderSingh-jx5sl
@RavinderSingh-jx5sl Жыл бұрын
Good videos, but how can we test FluentValidation?
@MilanJovanovicTech
@MilanJovanovicTech Жыл бұрын
You can create a command and pass it to a validator instance for testing
@shuvbhowmickbestin
@shuvbhowmickbestin 2 ай бұрын
And obviously VS2022 sets the project up with 99+ changes!
@MilanJovanovicTech
@MilanJovanovicTech 2 ай бұрын
Hmm?
@TrOgaN_
@TrOgaN_ 7 ай бұрын
What are you testing against to find the uniqueness of the email, a database? What is the state of of the database and how are you controlling it? Next time you run your test is will fail as you have already added the user to the db!
@MilanJovanovicTech
@MilanJovanovicTech 7 ай бұрын
We can always clear the DB before running the test
@TrOgaN_
@TrOgaN_ 7 ай бұрын
@@MilanJovanovicTech We can but we didn't, we didn't even mention the database.
@MilanJovanovicTech
@MilanJovanovicTech 7 ай бұрын
@@TrOgaN_ Check out a few videos I've done on integration testing
@TrOgaN_
@TrOgaN_ 7 ай бұрын
@@MilanJovanovicTech This isn't integration testing, it's unit testing jtbc. i'm reluctant to look at any more videos sorry!
@stefanbogdanovic590
@stefanbogdanovic590 2 жыл бұрын
NSubstitute + Fluent Assertions + xUnit
@MilanJovanovicTech
@MilanJovanovicTech 2 жыл бұрын
How is NSubstitute compared to Moq?
@stefanbogdanovic590
@stefanbogdanovic590 2 жыл бұрын
@@MilanJovanovicTech For me personally better and easier API to work with.
@Eriksonlove69
@Eriksonlove69 Жыл бұрын
how can I get this repo?
@MilanJovanovicTech
@MilanJovanovicTech Жыл бұрын
Were you able to get access on Patreon?
@paulbarton2280
@paulbarton2280 2 жыл бұрын
Would have been nice to see more of a red, green, refactor approach apposed to you just intuitively knowing your initial test was not sound.
@MilanJovanovicTech
@MilanJovanovicTech 2 жыл бұрын
Hey Paul :) I'm not familiar with TDD approach, so I didn't go down that route. But I'll definitely use that for testing the Domain layer, that would be a great learning opportunity for me.
@CSharp_Dev2022
@CSharp_Dev2022 2 жыл бұрын
Can you talk about docker
@MilanJovanovicTech
@MilanJovanovicTech 2 жыл бұрын
Yes!
@CSharp_Dev2022
@CSharp_Dev2022 2 жыл бұрын
@@MilanJovanovicTech It will be great if you talk about docker and how can we implemented in c#. Thank you
@skarabei2303
@skarabei2303 9 ай бұрын
What if handler is void
@MilanJovanovicTech
@MilanJovanovicTech 9 ай бұрын
Test if the mocks were called with correct values
@CodeBallast
@CodeBallast Жыл бұрын
Why not just put the Arrange lines in the constructor. In that way you want have all your duplicate code.
@MilanJovanovicTech
@MilanJovanovicTech Жыл бұрын
Good suggestion
@dxs1971
@dxs1971 2 жыл бұрын
Email should be ValueObject
@MilanJovanovicTech
@MilanJovanovicTech 2 жыл бұрын
Isn't it?
@dxs1971
@dxs1971 2 жыл бұрын
@@MilanJovanovicTech no it is just a string
@fernandocalmet
@fernandocalmet 2 жыл бұрын
Great video! Thank you Milan
@MilanJovanovicTech
@MilanJovanovicTech 2 жыл бұрын
Thanks, Fernando! How do you write unit tests?
@fernandocalmet
@fernandocalmet 2 жыл бұрын
@@MilanJovanovicTech I have done it before, but unfortunately it is not currently applied in the company where I work for. The TDD culture still needs to be integrated here. However with this type of content I have the basis to continue practicing by myself. It would be interesting if you also make an integration testing video. Thanks for sharing Milan😃
@MilanJovanovicTech
@MilanJovanovicTech 2 жыл бұрын
@@fernandocalmet Integration testing is definitely coming!
@richardaubin1951
@richardaubin1951 2 жыл бұрын
Have you had a chance to use/review FakeItEasy?
@MilanJovanovicTech
@MilanJovanovicTech 2 жыл бұрын
Only heard of it, never used it
@EHBRod13
@EHBRod13 2 жыл бұрын
Thanks for the video! Super helpful!
@MilanJovanovicTech
@MilanJovanovicTech 2 жыл бұрын
Glad you liked it :)
Why I Use The Unit of Work Pattern With EF Core | Clean Architecture
11:34
Writing tests in .NET using xUnit -  xUnit Tutorial
25:50
Nick Chapsas
Рет қаралды 129 М.
БУ, ИСПУГАЛСЯ?? #shorts
00:22
Паша Осадчий
Рет қаралды 2,9 МЛН
Молодой боец приземлил легенду!
01:02
МИНУС БАЛЛ
Рет қаралды 1,9 МЛН
xUnit or NUnit? Picking the Right Testing Library
10:00
Nick Chapsas
Рет қаралды 50 М.
Adding Filtering, Sorting And Pagination To a REST API | .NET 7
24:02
Milan Jovanović
Рет қаралды 59 М.
Working on Online Multiplayer Game (Typescript)
Web Dev Cody
Рет қаралды 34
Mocking in C# Unit Tests - How To Test Data Access Code and More
1:02:34
Learn Unit Test with .Net 6 with xUnit and MOQ
1:29:24
Mohamad Lawand
Рет қаралды 32 М.
EF Core Performance Optimization Challenge | 233x FASTER
14:42
Milan Jovanović
Рет қаралды 69 М.
Complete Backend API in Golang (JWT, MySQL & Tests)
1:37:57
Tiago
Рет қаралды 121 М.
Today's Console Pick 🔥
0:11
Gleb POV
Рет қаралды 1,3 МЛН
Новый матовый iMac M4
0:59
Romancev768
Рет қаралды 679 М.
Это ЛУЧШИЕ Смартфоны 2024 Года. Недорого и Качественно
15:23
Thebox - о технике и гаджетах
Рет қаралды 125 М.
Андроид - мечта геймера!😍
1:00
Корнеич
Рет қаралды 1,4 МЛН