2015-11-30 2 views
3

Je possède ce code de test unitaire pour se moquant quelque chose:Comment tester un cas de test d'unité paramétré avec un argument jmockit supplémentaire?

import org.junit.Assert; 
import org.junit.Test; 
import mockit.*; 
import org.junit.runner.RunWith; 
import com.googlecode.zohhak.api.TestWith; 
import com.googlecode.zohhak.api.runners.ZohhakRunner; 


@RunWith(ZohhakRunner.class) 
public class PersonTest{ 
    @Test 
    public void testGetName(@Capturing final Person p) { 
     // I need P object for mocking; 
     Assert.assertTrue(true); 
    } 

    @TestWith({ 
      "1, 1", 
      "2, 2" 
    }) 
    public void test_is_euqal(int input, int expected, @Capturing final Person p){ 
     // ... some code here ... 
     // I need P Object for mocking but don't want to use it as parametrized 
     Assert.assertEquals(Integer.valueOf(expected), Integer.valueOf(input)); 
    } 
} 
premier test

(testGetName) est OK, mais le second test jet ArrayIndexOutOfBoundsException exception parce que j'utilise @capturing dans les arguments. est-il un moyen d'envoyer un argument à un cas de test et ne pas parametrized sans lancer aucune exception ArrayIndexOutOfBoundsException?

+0

Vous souhaitez un objet de personne utilisateur facultativement en argument? –

+0

@BilalShah oui. mais il jette une exception :(parce que j'utilise 3 arguments dans la définition de testcase mais définit 2 valeurs dans '@TestWith ({....})' Je veux un moyen d'utiliser l'objet 'Person' dans les arguments qui ne jette pas une exception (comme le premier cas de test) – shotgunner

Répondre

-3

Essayez cette

public void test_is_euqal(int input, int expected, Person p=null) 
+0

L'annotation '@ Capture 'n'accepte pas cette syntaxe – shotgunner

0

Réponse courte: Vous ne pouvez pas faire cela.

réponse plus longue:

En fait, vous essayez de combiner automatiquement 2 différents coureurs qui, en général, est impossible dans JUnit. Les plus simples solutions de contournement que je peux penser est:

  • créer des objets fantaisie à l'intérieur de la méthode d'essai manuellement sans @Capturing annotation
  • utilisant @Capturing sur les champs plutôt que sur les paramètres (je sais, il peut être gênant)
  • combinaison des deux ci-dessus
+1

Veuillez prendre quelques secondes supplémentaires pour inclure la casse et la ponctuation dans vos publications. – meagar

0

Utilisation des SoftAssertions de AssertJ vous émulent les paramètres dans un seul test:

@Tested 
    private Foo foo; 

    @Mocked 
    private Baz baz; 

    @Test 
    public void givenFoo_WhenGetBar_ShouldBeExpected() throws Exception { 

     List<Parameters> parametersList = asList(
       new Parameters(param1, expecte1), 
       new Parameters(param2, expected2), 
       new Parameters(param3, expeted3)); 

     // For each parameter set expectations and get actual 
     // needs to be in for loop instead of forEach if exceptions are checked 
     for (final Parameters parameters : parametersList) { 

      new Expectations() {{ 
       baz.get(); 
       result = parameters.param; 
      }}; 

      parameters.actual = foo.getBar(); 
     } 

     // This will give a test case name and assert on each item even if another item fails 
     // the same functionality of parameterized tests but in a single Test 
     assertSoftly(softly -> parametersList 
       .forEach(parameters -> softly.assertThat(parameters.actual) // doesn't short circuit 
         .as(parameters.toString()) // test case name 
         .isEqualTo(parameters.expected))); 

    } 

    private class Parameters { 
     Parameters(ParamType param, ExpectedType expected){ 
      this.param = param; 
      this.expected = expected; 
     } 
     private final ParamType param; 
     private final ExpectedType expected; 
     private ActualType actual; 

     @Override 
     public String toString(){ 
      return String.format("param: %s expected: %s",param,expected); 
     } 
    }