Re: Mocking XNA Game object

"Hey XNA Game object, you're so ugly that even your private constuctor won't make an instance of you"....

I know a couple of people have tried this but I can't find the forum posts right now... I'm pretty sure they came to the conclusion that it was a lot of work to mock the whole game object up enough to get unit tests out of it.

Re: Mocking XNA Game object

Hopefully Shawn will pop in, I seem to remember he had an opinion on this - they use Unit Testing on the XNA Framework so they are ware of the issues.

Its trivial to mock object that sort of car object. But the Game object is what is running the whole game, all your code is called by it. So you are going to have to implement almost all of it and then some just so that the code you are trying to test gets called properly... At least thats what I remember from the other threads... there's plenty of TDD folk round here to correct me though.

Re: Mocking XNA Game object

Successful unit testing is all about minimizing dependencies. If your car object requires a mock Game instance in order to run its unit tests, that strikes me as an overly-close coupling. Why does the car class require a Game at all? Break that dependency, and your problem goes away.

The XNA Framework does not support mocking types such as Game or GraphicsDevice. We decided it would impose too much runtime overhead if we made everything an interface in order to enable that. You could build your own abstraction layer on top of our types, then mock that abstraction of your own, but:

a) that's going to be a lot of work
b) you're going to pay a perf penalty
c) are you sure you really need this in any case?

I'm not convinced that for instance testing graphics code with a mock graphics device is particularly useful. If you factor your code right, you can test all your game logic without ever creating a Game or GraphicsDevice. But when it comes to testing your graphics, you really need to draw some stuff and then check that it drew the right image for the test to be valid. For that, you need to create an actual GraphicsDevice, rather than just mocking all the graphics API to noop.

Re: Mocking XNA Game object

Your car can still have Update and Draw methods; just don't make it derive from DrawableGameComponent. Then just call those methods from your game or another place and let it still handle it's own logic and drawing.

Alternatively you could build your own base game component class that doesn't rely on the Game object, but instead just requires an IServiceProvider. Then you can implement your own IServiceProvider to give the component an IGraphicsDeviceService and you'll be all set. Here are a couple of my classes: BasicGameComponent (requires neither Game nor IServiceProvider) and BasicDrawableGameComponent (requires an IServiceProvider instead of a Game). The only note is that the Initialize method in BasicDrawableGameComponent uses an extension method I wrote for IServiceProvider to get a service out using generics; just replace that with the normal GetService method and you'll be fine.

Re: Mocking XNA Game object

Successful unit testing is all about minimizing dependencies. If your car object requires a mock Game instance in order to run its unit tests, that strikes me as an overly-close coupling. Why does the car class require a Game at all? Break that dependency, and your problem goes away.

To be fair, our GameComponent class has this dependency, and we encourage people to use it. If the car class derives from GameComponent, then the developer was coerced into the overly-close coupling by the XNA Framework!

While developers can go ahead and implement their own IGameComponent and IUpdateable in a class that doesn't depend on Game, that's a bit of a pain and it's a shame we didn't do it for them in the first place. For that matter, why doesn't IGameComponent.Initialize take an IServiceProvider parameter instead of forcing the class implementing the interface to have an implementation-specific method of connecting to its hosting environment?

Considering the public methods on Game, what is the chance of a noticeable performance penalty in providing an abstraction of it to game components? The public members of Game don't get called that many times per frame. In the case of the properties, which are mainly there for convenience, the values can easily be cached locally to resolve any issues that might come up.

For GraphicsDevice, on the other hand, I completely agree with you. :)

Re: Mocking XNA Game object

Your car can still have Update and Draw methods; just don't make it derive from DrawableGameComponent. Then just call those methods from your game or another place and let it still handle it's own logic and drawing.

Alternatively you could build your own base game component class that doesn't rely on the Game object, but instead just requires an IServiceProvider. Then you can implement your own IServiceProvider to give the component an IGraphicsDeviceService and you'll be all set. Here are a couple of my classes: BasicGameComponent (requires neither Game nor IServiceProvider) and BasicDrawableGameComponent (requires an IServiceProvider instead of a Game). The only note is that the Initialize method in BasicDrawableGameComponent uses an extension method I wrote for IServiceProvider to get a service out using generics; just replace that with the normal GetService method and you'll be fine.

How did you know that you had to implement the IGameComponent, IUpdateable and in particular IDisposable
interfaces.

Also, if this is the case, will I be able to do things like Keyboard.GetState() from this kind of custom-crafted game component? Does it not require a dependency on the Game object?

Re: Mocking XNA Game object

Successful unit testing is all about minimizing dependencies. If your car object requires a mock Game instance in order to run its unit tests, that strikes me as an overly-close coupling. Why does the car class require a Game at all? Break that dependency, and your problem goes away.

To be fair, our GameComponent class has this dependency, and we encourage people to use it. If the car class derives from GameComponent, then the developer was coerced into the overly-close coupling by the XNA Framework!

While developers can go ahead and implement their own IGameComponent and IUpdateable in a class that doesn't depend on Game, that's a bit of a pain and it's a shame we didn't do it for them in the first place. For that matter, why doesn't IGameComponent.Initialize take an IServiceProvider parameter instead of forcing the class implementing the interface to have an implementation-specific method of connecting to its hosting environment?

Considering the public methods on Game, what is the chance of a noticeable performance penalty in providing an abstraction of it to game components? The public members of Game don't get called that many times per frame. In the case of the properties, which are mainly there for convenience, the values can easily be cached locally to resolve any issues that might come up.

For GraphicsDevice, on the other hand, I completely agree with you. :)

Re: Mocking XNA Game object

How did you know that you had to implement the IGameComponent, IUpdateable and in particular IDisposable
interfaces.

IGameComponent is required to be added to the Components collection and IUpdateable is required for it to have an Update method be automatically called by the game. IDisposable is there because it's on the standard GameComponent/DrawableGameComponent so I wanted to mimic the functionality.

Also, if this is the case, will I be able to do things like Keyboard.GetState() from this kind of custom-crafted game component? Does it not require a dependency on the Game object?

No, there is no dependency on the Game class for the Keyboard class to work.

Re: Mocking XNA Game object

Also, if this is the case, will I be able to do things like Keyboard.GetState() from this kind of custom-crafted game component? Does it not require a dependency on the Game object?

No, there is no dependency on the Game class for the Keyboard class to work.

But this is another dependency that might be worth breaking...

If your Car class directly calls Keyboard.GetState(), then you will not be able to write automated unit tests for any of its functionality that depends on that keyboard input (you'd have to sit at the computer while the test is running to press the right keys at just the right times).

But if you wrote your Car.Update method to take a KeyboardState as a parameter, and have your main game do the GetState part before it passes this input when it calls car.Update, then you can easily write unit tests that construct their own KeyboardState with whatever value you need for that test, never touching the actual keyboard, as your unit test has total control to pass any fake input data it likes into car.Update.

Re: Mocking XNA Game object

For classes that are going to require unit testing, I generally use a subroutine for all the real work.

I'll try and explain...

class Tom derives from *** and overrides ***.Update and ***.Draw

in Tom I use the functions that overide Update and Draw to set up the input variables for a subroutine that actually does the work

I then create a public method Tom.DebugUpdate and Tom.DebugDraw which set up all the input variables and call the same subroutine.

You can then call the debug versions should you need to instead of the real versions.

This works particularly well when debugging shaders that render to textures, I cannot get pixwin to debug shader code while rendering to a texture, it just crashes on my machine, so the debug versions just draw to the screen and I can then debug them at my leisure.

Re: Mocking XNA Game object

You could actually instantiate a real Game object for every test couldn't you? It would be horribly slow but it would work? If that is the case would it be possible to cache that Game object and reuse it for each test in the run, 'reseting' it between tests? I haven't done any GameComponent unit testing so I'm just guessing here..

Re: Mocking XNA Game object

You could actually instantiate a real Game
object for every test couldn't you? It would be horribly slow but it
would work? If that is the case would it be possible to cache that Game
object and reuse it for each test in the run, 'reseting' it between
tests? I haven't done any GameComponent unit testing so I'm just
guessing here..

Oh, but WHY do I need that painstaking way of doing this?

Stainless:

For classes that are going to require unit testing, I generally use a subroutine for all the real work.

I'll try and explain...

class Tom derives from *** and overrides ***.Update and ***.Draw

in Tom I use the functions that overide Update and Draw to set up the input variables for a subroutine that actually does the work

I then create a public method Tom.DebugUpdate and Tom.DebugDraw which set up all the input variables and call the same subroutine.

You can then call the debug versions should you need to instead of the real versions.

This works particularly well when debugging shaders that render to textures, I cannot get pixwin to debug shader code while rendering to a texture, it just crashes on my machine, so the debug versions just draw to the screen and I can then debug them at my leisure.

It's a pretty simple solution, and quite crude, but it does work.

If I understand you correctly, then all the code that you want to be able to test has a few "special" functions (DebugDraw, DebugUpdate etc...), that setup the testing state for that code?

Does it not defeat the purpose of testing, in that you should really be testing the functions actually in use by your game and not the ones that are not?
DebugUpdate may work fine with your custom setup code, but when used on it's own it might fail when passed a null value of some kind, for example. Also when you refactor your code how can you be sure that your custom setup functions reflect the refactored code correctly, and not the "old" code?

I need a way to test my code without any modifications to it. Also I don't want to add a lot of methods that are really only good for testing, since that puts additional requirements on my design which have nothing to do with the game itself.

Similarly when people suggest making an IGame interface, I don't see the reason why I need to "hack" my code just to accommodate testing.
I want to test Game Components and not Components with my custom IGame interface.

I would like to decouple my game components, but when I do, I just end up rewriting the Update, Draw, Initialize and LoadContent methods, in order to make them not accept the Game parameter. Essentially I am recreating the interface that game components implement.
So now I have 2 interfaces that do the same thing. Is it just me or is there some complexity issues here (especially in the case of framework updates for example).

I am but a newbie programmer, so any clarification would be appreciated.

Re: Mocking XNA Game object

Also, if this is the case, will I be able to do things like Keyboard.GetState() from this kind of custom-crafted game component? Does it not require a dependency on the Game object?

No, there is no dependency on the Game class for the Keyboard class to work.

But this is another dependency that might be worth breaking...

If your Car class directly calls Keyboard.GetState(), then you will not be able to write automated unit tests for any of its functionality that depends on that keyboard input (you'd have to sit at the computer while the test is running to press the right keys at just the right times).

But if you wrote your Car.Update method to take a KeyboardState as a parameter, and have your main game do the GetState part before it passes this input when it calls car.Update, then you can easily write unit tests that construct their own KeyboardState with whatever value you need for that test, never touching the actual keyboard, as your unit test has total control to pass any fake input data it likes into car.Update.

Re: Mocking XNA Game object

... when it comes to testing your graphics, you really need to draw some stuff and then check that it drew the right image for the test to be valid. For that, you need to create an actual GraphicsDevice, rather than just mocking all the graphics API to noop.

Re: Mocking XNA Game object

Successful unit testing is all about minimizing dependencies. If your car object requires a mock Game instance in order to run its unit tests, that strikes me as an overly-close coupling. Why does the car class require a Game at all? Break that dependency, and your problem goes away.

To be fair, our GameComponent class has this dependency, and we encourage people to use it. If the car class derives from GameComponent, then the developer was coerced into the overly-close coupling by the XNA Framework!

While developers can go ahead and implement their own IGameComponent and IUpdateable in a class that doesn't depend on Game, that's a bit of a pain and it's a shame we didn't do it for them in the first place. For that matter, why doesn't IGameComponent.Initialize take an IServiceProvider parameter instead of forcing the class implementing the interface to have an implementation-specific method of connecting to its hosting environment?

Huzzah! Stephen, why didn't they get you to design the framework ;)

The best solution is to write your own base classes and interfaces to avoid Game dependecies at all costs - use IServiceProvider instead. This also gives you a nice framework for putting your game framework into WinForms for editors etc.

Re: Mocking XNA Game object

I am not sure how I can write the "Car" class without the XNA dependencies.

I mean i need Update, and Draw methods, don't I? No matter how I write it.
But that means I either have to reuse XNA GameComponenet or create my own...erm.. GameComponent?

If I create my own I have 2 kinds of GameComponenets in my game + I have to create ComponentManager that essentially does what XNA Comp.Manager does...
With such luck - why use XNA-GameComponenets at all?

Re: Mocking XNA Game object

I mean i need Update, and Draw methods, don't I? No matter how I write it.

Yes.

Andriyko:

why use XNA-GameComponenets at all?

Exactly... Dont. See Nick's post above - it's really quite easy to roll your own. I agree it's a hassle to write your own "GameComponentCollection", but Reflector should help if there's functionality you need but aren't sure how to implement. You get the added bonus that you can customize 'til your heart's content.