views:

1264

answers:

6

I was wandering if it's possible to mock a Game object in order to test my DrawableGameComponent component?

I know that mocking frameworks need an interface in order to function, but I need to mock the actual Game object.

edit: Here is a link to respective discussion on XNA Community forums. Any help?

+2  A: 

You can use a tool called TypeMock that I believe does not require you to have an interface. Your other and more commonly followed method is to create a new class that inherits from Game and also implements an interface that you create that matches the Game object. You can then code against that interface and pass in your 'custom' Game object.

public class MyGameObject : Game, IGame
{
    //you can leave this empty since you are inheriting from Game.    
}

public IGame
{
    public GameComponentCollection Components { get; set; }
    public ContentManager Content { get; set; }
    //etc...
}

Its a bit tedious, but it lets you achieve mockability.

IAmCodeMonkey
Is there any way I can inherit from one thing instead of two?Also, what does inheriting from IGame give me? It seems like not inheriting from it changes nothing. Maybe I am just not clear on this, sorry.
drozzy
this wouldn't work, because the constructor to the drawablegamecomponent needs an instance of Game, not IGame ;-)
Joel Martinez
+3  A: 

frameworks like MOQ and Rhino Mocks don't specifically need an interface. They can mock any non-sealed and/or abstract class as well. Game is an abstract class, so you shouldn't have any trouble mocking it :-)

The one thing to note with at least those two frameworks is that to set any expectations on methods or properties, they must be virtual or abstract. The reason for this is that the mocked instance it generates needs to be able to override. The typemock mentioned by IAmCodeMonkey I believe has a way around this, but I don't think typemock is free, while the two I mentioned are.

As an aside, you can also check out a project of mine that could help in creating unit tests for XNA games without the need to make mocks: http://scurvytest.codeplex.com/

Joel Martinez
Thanks for the answer. Sorry but I don't really have much time to debug another framework. Looks interesting though.
drozzy
I'm tempted to give this a go. Only affraid to put another factor of uncertainty (new to XNA, new to TDD) in the process. Anybody has any XP with it?
borisCallens
@boris callens: I've used Rhino Mocks alot. It works very well.
Skurmedel
+3  A: 

You don't have to mock it. Why not make a fake game object?

Inherit from Game and override the methods you intend to use in your tests to return canned values or shortcut calculations for whatever methods/properties that you need. Then pass the fake to your tests.

Before mocking frameworks, people rolled their own mocks/stubs/fakes - maybe it's not as quick and easy, but you still can.

SnOrfus
I like it. Somehow the whirlwind of these frameworks fogged my path. I'll give it a try and get back to you here with the results!
drozzy
Sounds great. Good luck! I'm excited to know how it turns out because I have a 1/4 done game project of my own sitting on the back burner.
SnOrfus
After looking into this more, sadly I can't figure an easy way of doing this. Unless I fake a whole bunch of methods. I am not sure what sideeffects it will produce as well. Thanks though.
drozzy
+10  A: 

There are some good posts in that forum on the topic of unit testing. Here's my personal approach to unit testing in XNA:

  • Ignore the Draw() method
  • Isolate complicated behavior in your own class methods
  • Test the tricky stuff, don't sweat the rest

Here's an example of a test to confirm that my Update method moves Entities the right distance between Update() calls. (I'm using NUnit.) I trimmed out a couple lines with different move vectors, but you get the idea: you shouldn't need a Game to drive your tests.

[TestFixture]
public class EntityTest {
    [Test]
    public void testMovement() {
        float speed = 1.0f; // units per second
        float updateDuration = 1.0f; // seconds
        Vector2 moveVector = new Vector2(0f, 1f);
        Vector2 originalPosition = new Vector2(8f, 12f);

        Entity entity = new Entity("testGuy");
        entity.NextStep = moveVector;
        entity.Position = originalPosition;
        entity.Speed = speed;

        /*** Look ma, no Game! ***/
        entity.Update(updateDuration);

        Vector2 moveVectorDirection = moveVector;
        moveVectorDirection.Normalize();
        Vector2 expected = originalPosition +
            (speed * updateDuration * moveVectorDirection);

        float epsilon = 0.0001f; // using == on floats: bad idea
        Assert.Less(Math.Abs(expected.X - entity.Position.X), epsilon);
        Assert.Less(Math.Abs(expected.Y - entity.Position.Y), epsilon);
    }
}

Edit: Some other notes from the comments:

My Entity Class: I chose to wrap all my game objects up in a centralized Entity class, that looks something like this:

public class Entity {
    public Vector2 Position { get; set; }
    public Drawable Drawable { get; set; }

    public void Update(double seconds) {
        // Entity Update logic...
        if (Drawable != null) {
            Drawable.Update(seconds);
        }
    }

    public void LoadContent(/* I forget the args */) {
        // Entity LoadContent logic...
        if (Drawable != null) {
            Drawable.LoadContent(seconds);
        }
    }
}

This gives me a lot of flexibility to make subclasses of Entity (AIEntity, NonInteractiveEntity...) which probably override Update(). It also lets me subclass Drawable freely, without the hell of n^2 subclasses like AnimatedSpriteAIEntity, ParticleEffectNonInteractiveEntity and AnimatedSpriteNoninteractiveEntity. Instead, I can do this:

Entity torch = new NonInteractiveEntity();
torch.Drawable = new AnimatedSpriteDrawable("Animations\litTorch");
SomeGameScreen.AddEntity(torch);

// let's say you can load an enemy AI script like this
Entity enemy = new AIEntity("AIScritps\hostile");
enemy.Drawable = new AnimatedSpriteDrawable("Animations\ogre");
SomeGameScreen.AddEntity(enemy);

My Drawable class: I have an abstract class from which all my drawn objects are derived. I chose an abstract class because some of the behavior will be shared. It'd be perfectly acceptable to define this as an interface instead, if that's not true of your code.

public abstract class Drawable {
    // my game is 2d, so I use a Point to draw...
    public Point Coordinates { get; set; }
    // But I usually store my game state in a Vector2,
    // so I need a convenient way to convert. If this
    // were an interface, I'd have to write this code everywhere
    public void SetPosition(Vector2 value) {
        Coordinates = new Point((int)value.X, (int)value.Y);
    }

    // This is overridden by subclasses like AnimatedSprite and ParticleEffect
    public abstract void Draw(SpriteBatch spriteBatch, Rectangle visibleArea);
}

The subclasses define their own Draw logic. In your tank example, you could do a few things:

  • Add a new entity for each bullet
  • Make a TankEntity class which defines a List, and overrides Draw() to iterate over the Bullets (which define a Draw method of their own)
  • Make a ListDrawable

Here's an example implementation of ListDrawable, ignoring the question of how to manage the list itself.

public class ListDrawable : Drawable {
    private List<Drawable> Children;
    // ...
    public override void Draw(SpriteBatch spriteBatch, Rectangle visibleArea) {
        if (Children == null) {
            return;
        }

        foreach (Drawable child in children) {
            child.Draw(spriteBatch, visibleArea);
        }
    }
}
ojrac
Could you show me your "Entity" interface? What is it? A component? A custom class?
drozzy
It's a custom class -- every game object I render uses it. I specifically avoided GameComponents for everything but my input handler and the http://creators.xna.com/en-US/samples/gamestatemanagement ScreenManager. It defines methods like Update(double time) which moves it speed * time in the direction of NextStep.
ojrac
In order to support multiple types of drawables (sprites, animated sprites, particles), my Entity *contains* a Drawable -- an abstract class that handles the Draw() calls.
ojrac
Could you elaborate on "Entity *contains* a Drawable" and how it handles the draw calls? Does it not just create another dependency of some sort (I can't think of how yet).
drozzy
I set my class structure up to allow interesting inheritance -- for example, an AIEntity that extends Entity. What if I want an AIEntity that's rendered as a particle effect (like a target-seeking magic effect, for example)? I'd have to make an AIEntity subclass ParticleEffectAIEntity. And if I want to make a NonInteractiveEntity (an immobile torch no one can pick up) that has a particle effect too (for the flames). I'd have to make another ParticleEffectNonInteractiveEntity.
ojrac
The alternative: my entity contains a reference to an abstract object, the Drawable. Then, on every Entity.Draw() call, I just run if (Drawable != null) { Drawable.Draw(); }. That way, I can reuse drawing code and keep it isolated from my game logic. Plus, the more I separate these functions, the easier it gets to test. I can create a new AnimatedDrawable and confirm that CurrentFrame changes at the right rate as I call AnimatedDrawable.Update()
ojrac
1. Why abstract object and not an interface?2. How does draw know how to draw an object? What if the object, tank, for example, has List<bullets> that it needs to draw?PS: Thanks for help btw. Great if you put that stuff into answer as well.
drozzy
I've added to the question this time. For answers, skip to the "My Drawable Class" section.
ojrac
Thanks. This gave me a few ideas on how to structure my game. It seems gamecompoenents are not all-in-one solution after all.
drozzy
This is where I got my start: http://www.thehazymind.com/category/xna/
ojrac
A: 

For a starting point on something like this, I would hit up the XNA WinForms Sample. Using this sample as a model, it appears that one way to visualize components in a WinForm is to create a control for it in the same style as the SpinningTriangleControl from the sample. This demonstrates how to render XNA code without a Game instance. Really the Game isn't important, its what it does for you that matters. So what you would do is create a Library project which has the Load/Draw logic of the Component in a class and in your other projects, create a Control class and a Component class which are wrappers for the library code in their respective environments. This way, the code your testing isn't duplicated and you don't have to worry about writing code that'll always be viable in two different scenarios.

Jeremy
Sorry but without reading that sample, your answer doesn't make much sense. I'll check it out at home later.
drozzy
Well the gist of the idea is that you keep the logic for your rendering in a separate class and you write 2 classes that are basically shells for that render logic in their respective environments--GameComponent and WinForms Control. So you're not really writing a Component that fakes a Game instance, you're writing a Control that never uses ones and sharing the implementation between the two presentation classes.
Jeremy
+1  A: 

I'm gonna piggy back on your post if you don't mind since mine seems to be less active and you already put your rep on the line ;)

As I read through your posts (both here & XNAForum) I'm thinking it's both the framework that could be more approachable and my (our) design that's not flawless.

The framework could have be designed to be easier to extended. I'm having a hard time to believe Shawn's main argument of a perf hit on interfaces. To back me up his colleague says the perf hit could be easely evaded.
Do note that the framework already has an IUpdatable and IDrawable interface. Why not go all the way?

On the other hand I also think that indeed my (and your) design are not flawless. Where I don't depend on the Game object, I do depend on the GraphicsDevice object a lot. I'm gonna look at how I can circumvent this. It's gonna make code more complicated, but I think I can indeed break those dependencies.

borisCallens
True dat. For example one challenge I have is whether to pass a sprite batch from a constructor or create one from within the class. Passing it through constructor makes the code more decoupled, but then I have to make assumptions on where I call sprite_batch.begin() and end() calls.
drozzy
Jeps, had the same thing. I'm passing it to the constructor now because I don't want my class to know what it looks like. I think this makes them portable to other games.
borisCallens
Also, begin()-ing and end()-ing them in every class I can imagine could cause a noticable slowdown.
borisCallens
I am not sure about the slow down, I read in one book or article that it does not
drozzy
That would change the whole idea indeed. I should search a bit on that. But if there is no perf hit implied, I don't see why these methods would be there in the first place..
borisCallens