En développant la réponse de David avec qui je suis totalement d'accord avec vous, vous devriez créer un wrapper pour Random. J'ai écrit à peu près la même réponse à ce sujet plus tôt dans une question similaire, alors voici une "version des notes de Cliff".
Ce que vous devez faire est de créer d'abord le wrapper en tant qu'interface (ou classe abstraite):
public interface IRandomWrapper {
int getInt();
}
Et la classe concrète pour cela ressemblerait à ceci:
public RandomWrapper implements IRandomWrapper {
private Random random;
public RandomWrapper() {
random = new Random();
}
public int getInt() {
return random.nextInt(10);
}
}
Disons que votre classe est la suivante:
class MyClass {
public void doSomething() {
int i=new Random().nextInt(10)
switch(i)
{
//11 case statements
}
}
}
Afin d'utiliser correctement IRandomWrapper, vous devez modifier votre classe pour la prendre comme membre (via un constructeur ou un 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
}
}
}
Vous pouvez maintenant tester le comportement de votre classe avec l'encapsuleur, en vous moquant de l'encapsuleur. Vous pouvez le faire avec un cadre de simulation, mais c'est aussi facile à faire par vous-même:
public class MockedRandomWrapper implements IRandomWrapper {
private int theInt;
public MockedRandomWrapper(int theInt) {
this.theInt = theInt;
}
public int getInt() {
return theInt;
}
}
Étant donné que votre classe attend quelque chose qui ressemble à un, IRandomWrapper
vous pouvez maintenant utiliser celui simulé pour forcer le comportement dans votre test. Voici quelques exemples de tests JUnit:
@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
}
J'espère que cela t'aides.
Vous pouvez (devez) encapsuler le code de génération aléatoire dans une classe ou une méthode, puis le simuler / le remplacer pendant les tests pour définir la valeur souhaitée, afin que vos tests soient prévisibles.
la source
Vous avez une plage spécifiée (0-10) et une granularité spécifiée (nombres entiers). Ainsi, lors des tests, vous ne testez pas avec les nombres aléatoires. Vous testez dans une boucle qui frappe tour à tour chaque cas. Je conseillerais de passer le nombre aléatoire dans une sous-fonction contenant l'instruction case, ce qui vous permet de simplement tester la sous-fonction.
la source
Vous pouvez utiliser la bibliothèque PowerMock pour simuler la classe Random et bloquer sa méthode nextInt () pour renvoyer la valeur attendue. Pas besoin de changer votre code d'origine si vous ne le souhaitez pas.
J'utilise PowerMockito et je viens de tester une méthode similaire à la vôtre. Pour le code que vous avez publié, le test JUnit devrait ressembler à ceci:
Vous pouvez également bloquer l'appel nextInt (int) pour recevoir n'importe quel paramètre, au cas où vous voudriez ajouter plus de cas à votre commutateur:
Joli, non? :)
la source
Utilisez QuickCheck ! Je viens de commencer à jouer avec ça récemment et c'est incroyable. Comme la plupart des idées sympas, cela vient de Haskell, mais l'idée de base est qu'au lieu de donner à vos tests des cas de test prédéfinis, vous laissez votre générateur de nombres aléatoires les construire pour vous. De cette façon, au lieu des 4-6 cas que vous trouveriez probablement dans xUnit, vous pouvez demander à l'ordinateur d'essayer des centaines ou des milliers d'entrées et de voir lesquelles ne sont pas conformes aux règles que vous avez définies.
QuickCheck essayera également de le simplifier lorsqu'il trouvera un cas défaillant afin qu'il puisse trouver le cas le plus simple possible qui échoue. (Et bien sûr, lorsque vous trouvez un cas défaillant, vous pouvez également le créer dans un test xUnit)
Il semble y avoir au moins deux versions pour Java, donc cette partie ne devrait pas poser de problème.
la source