0

I am using C# with Unity3D.

There is an object type called Transform that I cannot directly instantiate.

I want to do some unit testing on a function that uses Transform.

Is this the correct way to do it?

Use the adapter pattern by:

  • creating a class (TransformAdapter) that has the same functionality as Transform
  • (when running for real) extending TransformAdapter, with a class called UnityTransform, that holds a Transform and just forwards on any functionality to Transform.
  • (when running in unit test) extending TransformAdapter, with a class caled MockTransform, that just holds values set by my unit test.

Update:

It appears that in many situations, I don't need to create abstract classes to mock out the objects, as I can instantiate the objects from unit tests if I run the unit tests from the Unity3d Unit Testing window. I cannot instantiate the objects if running the tests from MonoDevelop.

Ginger
  • 8,320
  • 12
  • 56
  • 99
  • Where do you *normally* get transforms from? Are there factory methods to create them, for example? – Jon Skeet Jul 22 '14 at 06:11
  • When I run a game run by Unity, it creates the transform objects. But my unit tests don't run the game, they just run small bits of code. I guess it would be like testing an Excel function, without running the full Excel. Are you the legendary Jon Skeet mentioned here? http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags – Ginger Jul 22 '14 at 06:13
  • 1
    Yes, I'm the same Jon Skeet - but back to your question. Can you add links to Unity documentation? Even if your unit tests don't run the full game, there may well be a way *somehow* of creating real Transform objects. If not, your adapter sounds like a good approach - although I'd probably just have an `ITransform` interface which is implemented by `TransformAdapter`, rather than making all your code use `TransformAdapter`. (So you'd have a separate implementation for tests... and that *wouldn't* be an adapter.) The adaptation is an implementation detail for the Unity version. – Jon Skeet Jul 22 '14 at 06:20
  • what unit testing framework are you using? Doesn't unity provide its own where transform is available? What do you intend to test? Perhaps you are trying to test something that's simply not worth testing, or doesn't need a transform. For instance if you need an object's position and rotation the corresponding testable function should take a vector3 and float as input rather than a transform. – CodeSmile Jul 22 '14 at 07:04
  • 1
    It sounds more like a proxy, since you don't have a family of related service providers with different, immutable APIs (adapter needs that, IMO). See my answer at http://stackoverflow.com/a/13323703/1168342 – Fuhrmanator Jul 23 '14 at 02:56
  • Thanks Jon Skeet - I will look at Interfaces. LearnCocos2D - I had a look at the Unity unit testing framework (from within it's Edit), but the examples don't seem to let me create the objects that I need. Fuhrmanator - thanks for the Proxy suggestion! – Ginger Jul 23 '14 at 05:41

1 Answers1

0

Unity3D doesn't really allow you to use your "normal" design patterns because of certain limitations, especially with it's internal serialization.

But specific to your case, in Unity3D a transform cannot exist without a GameObject, and vice-versa. Just use new GameObject("Insert Name Here") in conjunction with GetComponent() on the new transform. You could write a small factory to do this.

Selali Adobor
  • 2,060
  • 18
  • 30