75882

Unit testing XNA: Do I need to Mock my GraphicsDevice

Question:

I'm fooling around with the XNA framework.<br /> To help me around I made a helper class that looks like this:

ActorHolder + SpriteBatch (SpriteBatch) + ContentManager (ContentManager) - drawables (IList<IDrawable>) - updatables (IList<IUpdatable>) + ActorHolder(GraphicsDevice, ContentManager) + Draw(GameTime) + Update(GameTime) + AddActor(IActor) + RemoveActor(IActor) + GetCollidingActors(IActor)

Now I want to unit test this class. But as you see my constructor needs a graphics device and a contentmanager. While I think this makes sence in my application, it doesn't in my tests.<br /> Should I mock these two just in order to unit test or is my design flawed?

--UPDATE--<br /> I found a link to a project that might help out: <a href="http://scurvytest.codeplex.com/" rel="nofollow">http://scurvytest.codeplex.com/</a> Don't have any xp with it yet as coding has to make room for social life a bit.

--Note--<br /> Excuse me my UML French, my company doesn't use it so I never used it except back at school.

Answer1:

I am "mocking" the graphics device by actually creating a real one on an invisible window. Performance is surprisingly good - 12 seconds for about 1500 tests.

It allows me to test code which requires a graphics device and do some basic verification (eg. is the right texture set, has the vertex buffer been selected, etc.). This could be improved by using the reference rasterizer with the DirectX Debug Runtime to do more intensive checking.

If I need to verify what gets sent to the graphics device, I create an interface through which the code-under-test can send the vertices - which can then be easily mocked with standard mock object frameworks.

Check this question for another discussion about mocking XNA graphics device dependent classes: <a href="https://stackoverflow.com/questions/1308560/xna-mocking-texture2d" rel="nofollow">Mocking Texture2D</a>

Here are the classes I'm using to "mock" using a real graphics device: <a href="https://devel.nuclex.org/framework/browser/graphics/Nuclex.Graphics/trunk/Source/MockedGraphicsDeviceService.cs?rev=1046" rel="nofollow">MockedGraphicsDeviceService.cs</a>, <a href="https://devel.nuclex.org/framework/browser/graphics/Nuclex.Graphics/trunk/Source/MockedGraphicsDeviceService.Test.cs?rev=1046" rel="nofollow">MockedGraphicsDeviceService.Test.cs</a>

(edit: fixed broken links)

Answer2:

This seems like a very valid usage scenario for mocking. I don't think there is a flaw in this design -

One reason mocking exists is to help with filling in resource requirements of an interface that are not available at testing time, such as remote objects, or in your case, the graphics resources. Mocking the graphics device and content manager seems appropriate here, to me.

Answer3:

As I discovered from <strong><a href="https://stackoverflow.com/questions/804904/xna-mock-the-game-object" rel="nofollow">my other</a></strong> question, GraphicsDevice is not to be taken lightly. <a href="http://forums.xna.com/forums/t/30645.aspx" rel="nofollow">This discussion</a> on XNA community forums in particular points out why it is not a good idea to mock this out.

I am still searching for a good solution to this. However I am inclined to think that either:

<ul><li>it's a design flaw in my architecture (i should decouple my components more)</li> <li>it's a design flaw in the XNA </li> </ul>

Recommend

  • How to send and get data between Service and BroadcastReceiver?
  • .Net WikiText to HTML Parser [closed]
  • How to update DocumentText with another DocumentText
  • Measuring broadcast message latency using system clock, good idea?
  • Get Yahoo Contact List in C# application
  • wp-query category and has tag
  • How to animate float:left divs? [closed]
  • How to convert time String into NSDate?
  • show alert using jQuery-Impromptu if elements value is empty or zero
  • Getting the length of an array. Compiler errors.
  • Consecutive calls/evaluations in a form?
  • c# recurring event (like for a calendar)
  • Dropping support for JRE 1.3
  • Why dsofile.dll still need Office Installation?
  • HTMLcollection 0 list length, [n] returns undefined, converting to an array returns an empty array
  • Theme in user control
  • Design of Service Layer and Repositories in Microsoft MVC
  • Playing Video in JavaFX8
  • Fatal error on Windows XP when compiled with XP Targeting in Visual Studio 2015
  • Binding from within a ResourceDictionary in a Catel WPF UserControl
  • Regarding Static class in c# [duplicate]
  • Interpolation method that does not add unnecessary extremums
  • Error Installing Windows 10 development tools for Visual Studio 2015 RC on Windows 8.1
  • Basic defensive programming [duplicate]
  • Is there a Windows socket API call / option to “block” a range of ports à la SO_EXCLUSIVEADDRUSE
  • TFS - how do I sum child task hours to parent
  • How to make R's read_csv2() recognise the text characters properly
  • Allowing both email and username for authentication
  • Get one-time binding to work for ng-if
  • Validaiting emails with Net.Mail MailAddress
  • Which linear programming package should I use for high numbers of constraints and “warm starts” [clo
  • Javascript + PHP Encryption with pidCrypt
  • How do you troubleshoot character encoding problems?
  • Run Powershell script from inside other Powershell script with dynamic redirection to file
  • retrieve vertices with no linked edge in arangodb
  • using conditional logic : check if record exists; if it does, update it, if not, create it
  • Understanding cpu registers
  • How to CLICK on IE download dialog box i.e.(Open, Save, Save As…)
  • Add sale price programmatically to product variations
  • Django query for large number of relationships