Erweitern Sie Davids Antwort, der ich voll und ganz zustimme, dass Sie einen Wrapper für Random erstellen sollten. Ich habe ziemlich genau die gleiche Antwort darüber in einer ähnlichen Frage geschrieben, also hier eine "Cliff's Notes-Version" davon.
Was Sie tun sollten, ist zuerst den Wrapper als Schnittstelle (oder abstrakte Klasse) zu erstellen:
public interface IRandomWrapper {
int getInt();
}
Und die konkrete Klasse dafür würde so aussehen:
public RandomWrapper implements IRandomWrapper {
private Random random;
public RandomWrapper() {
random = new Random();
}
public int getInt() {
return random.nextInt(10);
}
}
Angenommen, Ihre Klasse ist die folgende:
class MyClass {
public void doSomething() {
int i=new Random().nextInt(10)
switch(i)
{
//11 case statements
}
}
}
Um den IRandomWrapper korrekt zu verwenden, müssen Sie Ihre Klasse so ändern, dass sie als Mitglied akzeptiert wird (über einen Konstruktor oder einen Setter):
public class MyClass {
private IRandomWrapper random = new RandomWrapper(); // default implementation
public setRandomWrapper(IRandomWrapper random) {
this.random = random;
}
public void doSomething() {
int i = random.getInt();
switch(i)
{
//11 case statements
}
}
}
Sie können jetzt das Verhalten Ihrer Klasse mit dem Wrapper testen, indem Sie den Wrapper verspotten. Sie können dies mit einem spöttischen Framework tun, aber dies ist auch einfach selbst zu tun:
public class MockedRandomWrapper implements IRandomWrapper {
private int theInt;
public MockedRandomWrapper(int theInt) {
this.theInt = theInt;
}
public int getInt() {
return theInt;
}
}
Da Ihre Klasse etwas erwartet, das aussieht wie eine IRandomWrapper
, können Sie jetzt die verspottete verwenden, um das Verhalten in Ihrem Test zu erzwingen. Hier einige Beispiele für JUnit-Tests:
@Test
public void testFirstSwitchStatement() {
MyClass mc = new MyClass();
IRandomWrapper random = new MockedRandomWrapper(0);
mc.setRandomWrapper(random);
mc.doSomething();
// verify the behaviour for when random spits out zero
}
@Test
public void testFirstSwitchStatement() {
MyClass mc = new MyClass();
IRandomWrapper random = new MockedRandomWrapper(1);
mc.setRandomWrapper(random);
mc.doSomething();
// verify the behaviour for when random spits out one
}
Hoffe das hilft.
Sie können (sollten) den Code für die zufällige Generierung in eine Klasse oder Methode einschließen und ihn dann während der Tests verspotten / überschreiben, um den gewünschten Wert festzulegen, damit Ihre Tests vorhersehbar sind.
quelle
Sie haben einen bestimmten Bereich (0-10) und eine bestimmte Granularität (ganze Zahlen). Beim Testen testen Sie also nicht mit den Zufallszahlen. Sie testen innerhalb einer Schleife, die nacheinander jeden Fall trifft. Ich würde empfehlen, die Zufallszahl in eine Unterfunktion zu übertragen, die die case-Anweisung enthält, mit der Sie die Unterfunktion einfach testen können.
quelle
Sie können die PowerMock-Bibliothek verwenden, um die Random-Klasse zu verspotten und ihre nextInt () -Methode zu stoppen, um den erwarteten Wert zurückzugeben. Sie müssen den ursprünglichen Code nicht ändern, wenn Sie dies nicht möchten.
Ich benutze PowerMockito und habe gerade eine ähnliche Methode wie Sie getestet. Der Code, den Sie für den JUnit-Test bereitgestellt haben, sollte ungefähr so aussehen:
Sie können auch den nextInt (int) -Aufruf unterbrechen, um einen beliebigen Parameter zu erhalten, falls Sie an Ihrem Switch weitere Fälle hinzufügen möchten:
Schön, nicht wahr? :)
quelle
Verwenden Sie QuickCheck ! Ich habe gerade erst damit angefangen und es ist erstaunlich. Wie die meisten coolen Ideen stammt sie von Haskell, aber die Grundidee ist, dass Sie Ihre Testfälle nicht vorkonfektionieren, sondern von Ihrem Zufallsgenerator für Sie erstellen lassen. Auf diese Weise können Sie anstelle der 4-6 Fälle, die Sie wahrscheinlich in xUnit gefunden haben, Hunderte oder Tausende von Eingaben vom Computer versuchen lassen und feststellen, welche nicht den von Ihnen festgelegten Regeln entsprechen.
Auch QuickCheck versucht, einen fehlgeschlagenen Fall zu vereinfachen, damit der einfachste Fall gefunden werden kann, bei dem ein Fehler auftritt. (Und wenn Sie einen fehlerhaften Fall finden, können Sie ihn natürlich auch in einen xUnit-Test integrieren.)
Es scheint mindestens zwei Versionen für Java zu geben, sodass ein Teil kein Problem darstellen sollte.
quelle