Hi, ich überlege derzeit wie ich meine "Manager"-Klassen am besten teste.
Mein Design: Ich befinde mich Design-technisch bei einem Entity-Component-System das viele Aspekte des Data-oriented Designs verwendet. Beispielsweise habe ich keine Entity-Klasse an sich sondern pro Komponente je eine Struktur - nennen wir sie
PhysicsData. Zu jeder Domäne (Physik, Animation, Rendering etc.) habe ich Manager- oder System-Klassen, z.B.
PhysicsSystem. Diese fungieren als Container der jeweiligen Daten (hier
PhysicsData, d.h. via Array) und führen auf diesen bestimmte Methoden aus, z.B.
bool PhysicsSystem::objectCanAccess(PhysicsData const & object, int x, int y) const;. Das öffentliche Interface ist relativ einfach gestrickt: Im Grunde calle ich jeden Frame die Update-Methoden der Systeme und diese erledigen die zum jeweiligen System zugehörige Arbeit. D.h. die
objectCanAccess()-Methode (zur Prüfung ob
object die Position (x,y) betreten kann - aus Sicht der Kollision) ist private, da das Physik-System seine Logik autonom verwendet. Weitere Methoden sind z.B.
void PhysicsSystem::interpolateMovement(PhysicsData& object, int elapsedTime) const; zu Interpolation der Bewegung.
Mein Problem: Ich möchte natürlich auch die privaten Methoden einem Unit-Test unterziehen. Nur sind die Methoden natürlich nicht public. Sie explizit zum Zweck des Unittestings öffentlich zu deklarieren, halte ich nicht für den richtigen Weg. Daher überlege ich, ob ich sie als protected umdeklariere und zum Unit-Test eine Ableitung der Klasse erstelle, z.B.
PhysicsSystemTest, die von
PhysicsSystem erbt. Dann könnte ich meine Testcases als Methoden meiner "Test-Klasse" schreiben, da ich innerhalb der Methoden dann auf protected-Member Zugriff habe.
Was haltet ihr von dieser Lösung?
Ich habe mal etwas gegoogelt: z.B. mit Boost's Unittesting Framework ist das prinzipiell möglich - nur muss ich die Methoden dann explizit zur Testsuite hinzufügen. Kennt da jemand eine elegante Alternative? Jede Methode manuell added ist ... mir irgendwie zu viel Aufwand
LG Glocke
PS: Ich weiß, dass "will private Methoden extern testen" nicht OO-like ist .. aber ehrlich gesagt halte ich den OO-Ansatz nicht für die absolute und letzte Wahrheit
Vielmehr "missbrauche" ich das Konzept der Klasse um für die Physik etc. mir ein einfaches Interface zu bauen und die Implementierung vor den anderen Systemen zu verstecken.
/EDIT: Was ich mir noch vorstellen könnte, wäre "mittels using als public zu erben", d.h.
|
C-/C++-Quelltext
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
#include <cassert>
class FooSystem {
protected:
bool foo(int a) { return a > 0; }
float bar(float x, float y) { return x * y; }
int lol(int u, int v) { return u + v; }
};
class FooSystemTest: public FooSystem {
public:
using FooSystem::foo;
using FooSystem::bar;
using FooSystem::lol;
};
int main() {
// assume this to be my unit test ^^
FooSystemTest sys;
assert(sys.foo(5) == true);
assert(sys.bar(3.f, 0.5f) == 1.5f);
assert(sys.lol(1, 2) == 3);
}
|