You kinda caught me at a bad time. I’m trying to release my game and, let’s be real, WoW just dropped a new expansion I think an example would be a good idea though, and I could probably roll this into some kind of tutorial video. I’ve got some ideas of how I might want to approach this, but maybe give me a bit to let some of the dust settle. I’ll see what I can do.
Unfortunately, unit testing isn’t something that seems to have penetrated very far into the game development world. At least, this seems to be the case from the research I’ve done. I kind of get it, it really does add a lot of additional effort to your development. I usually budget for at least 3 times what I think it’s going to take me to do without following testing practices. Personally, I find the benefits worth it… not only do you have high confidence in the code you write, the very act of trying to test your code just forces you into better coding practices. I accept that it’s not for everyone though, and given that, it doesn’t make a lot of sense for the MonoGame devs to spend time on it when they could focus on other things.
Fortunately, if you just focus on the functionality you need and wrap that, creating your own wrapper framework is fairly straight forward. When I get to the example, I’ll cover this as well
Constructor injection is your best bet. Not only is there less of a performance cost (no dictionary lookup in your dependency container), but it’s also much easier to test as you can pass your mocks directly into the class without having to worry about staging your dependency container. Having said that, you’ll still probably want some kind of dependency container anyway, where you can put objects you find you’ll need but don’t want to pass along everywhere.
Honestly, there’s no real best way, just the way that makes sense to you. Just be mindful of dependency container use… the best place to use them is to resolve dependencies that you pass into a constructor. The next best place is in a constructor itself. The worst place is in your Update or Draw methods, as the lookup will get called over and over.
Anyway, at this point I think your best bet is to just dive in and play around. You’ll know something isn’t quite right when you go to test it and it’s hard. When you bump into that, it’s time to refactor. That’s the nice thing about writing testable code. If you’re finding it hard to test, you probably need to take a different approach
Oh! One last note… there are definitely things you will not write tests for. For example, you don’t need to write tests for your wrapped MonoGame objects that implement your interfaces. You also don’t need to write tests for your MonoGame Game class. This is simply your entry point, direct it to some kind of IMainGame (or IViewEngine as you noted above) and then leave it alone. We generally trust that the API we are using works, but want to stage our code so we can test the interactions with it.