Reputation: 1310
I am having difficulty writing tests for a particular ViewModel which ties together several other ViewModels and their children. It's the most complex ViewModel in my application.
My ViewModel's structure mirrors the view's structure. It is injected with its children and its children are injected with their children.
It is very laborious to mock.
It is time consuming to mock due to the chain of dependencies. For example, say I have the structure MainViewModel.SubViewModel1.SubViewModel2 than I end up having to mock multiple layers because an action in MainViewModel may result in SubViewModel1 needing to check the visibility of SubViewModel2.
Is this the result of poor design?
Am I unit testing incorrectly?
Are there AutoMockers that will recursively mock my injected parameters?
Upvotes: 3
Views: 376
Reputation: 22320
The answer to your Q2 "Am I unit testing incorrectly" is "probably". Unit testing is about testing units in isolation. But some times its hard to do. You have few options:
Make SubViewModel1 to have a property which exposes the visibility of SubViewModel2, that way, when testing MainViewModel, you will mock/stub only SubViewModel1. And of course you will have a test if that property actually works :)
Now, the above is from "puristic" point of view. Sometimes, even if its the right thing to do from OO design point of view, it's not practical to do so.
So, you can try AutoFixture as an auto-mocking container, and it will prepare nested mocks.
Again, review your design, usually if you find out that something is hard to test, probably it's not well constructed, and does too much.
Upvotes: 2
Reputation: 17398
Well it's very easy to say it's bad design and it can tend to be so as well.
However there are cases that might require this. If your sure your in one of them cases then you got to live with it. If it's your most complicated VM then it's just logical that testing it will be your most complicated tests.
Finally I hope you do have some interface structure among your VM's to help you mock VM's accordingly. This will help you in such cases as if your using an IoC container you can in your tests just inject the Mock VM instead of the live one. This can either be an interface on the VM itself or quite a lot of people do prefer to extract these behaviors out into a service.
Upvotes: 2