Тестирование огурца с помощью PowerMockTestCase для имитации классов stati c - PullRequest
1 голос
/ 05 мая 2020

Я использую огурец BDD, testng, java, чтобы написать тест BDD. Я хотел бы высмеять классы stati c, чтобы написать свой тест. Однако, когда я пишу этот тестер, он не может инициализировать BDD сценарий ios.

Полный пример (обратите внимание на закомментированную строку PrepareForTest):

import gherkin.events.PickleEvent;
import io.cucumber.testng.CucumberOptions;
import io.cucumber.testng.PickleEventWrapper;
import io.cucumber.testng.TestNGCucumberRunner;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.testng.PowerMockTestCase;
import org.testng.Assert;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

import java.util.concurrent.TimeUnit;

import static org.mockito.Matchers.any;

@CucumberOptions(
        features = {
                "src/test/resources/features/sample"
        },
        glue = {
                "com.demo.stepdefinitions.sample"
        },
        plugin = {
                "pretty",
                "html:target/cucumber-reports/cucumber-pretty",
                "json:target/cucumber-reports/sampple-report.json",
                "rerun:target/cucumber-reports/sample-rerun.txt"
        }
)
//@PrepareForTest({Util.class})
public class TestngWithDataproviderTest extends PowerMockTestCase {
    private TestNGCucumberRunner testNGCucumberRunner;
    private void mockActiveBucket() {
        PowerMockito.mockStatic(Util.class);
        PowerMockito.when(Util.getBucketId(any(Long.class))).thenReturn(3);
    }

    @BeforeClass(alwaysRun = true)
    public void setUpClass() throws Exception {
        testNGCucumberRunner = new TestNGCucumberRunner(this.getClass());
    }

    @Test(dataProvider = "users")
    public void testMockStatic(String username){
        System.out.println("username: " + username);
        System.out.println("static test passed");
        mockActiveBucket();
        Assert.assertTrue(true);
    }

    @Test(groups = "cucumber scenarios", description = "Runs Cucumber Scenarios", dataProvider = "scenarios")
    public void testCucumberCcenario(PickleEventWrapper pickleEvent) throws Throwable {
        PickleEvent event = pickleEvent.getPickleEvent();
        mockActiveBucket();
        testNGCucumberRunner.runScenario(pickleEvent.getPickleEvent());
        Assert.assertTrue(true);
    }

    @DataProvider(name = "scenarios")
    public Object[][] scenarios() {
        Object[][] scenarios = testNGCucumberRunner.provideScenarios();
        return new Object[][]{{scenarios[0][0]}};
    }

    @DataProvider(name = "users")
    public Object[][] users() {
        return new Object[][]{{"user1"}, {"user2"}};
    }
}

class Util {
    public static int getBucketId(long eventTimestamp){
        Long minsPast5MinBoundary = (eventTimestamp % TimeUnit.MINUTES.toMillis(5))/TimeUnit.MINUTES.toMillis(1);
        return minsPast5MinBoundary.intValue();
    }
}

Приведенный выше тест не удается загрузить BDD сценарий ios dataProvider , если я включаю аннотацию PrepareForTest в тесте. Однако другой тест, который использует dataProvider , отлично работает в обоих случаях (включить или отключить PrepareForTest)

ERROR:

Data provider mismatch
Method: testCucumberCcenario([Parameter{index=0, type=io.cucumber.testng.PickleEventWrapper, declaredAnnotations=[]}])
Arguments: [(io.cucumber.testng.PickleEventWrapperImpl) "Sunday isn't Friday"]

    at org.testng.internal.reflect.DataProviderMethodMatcher.getConformingArguments(DataProviderMethodMatcher.java:45)
    at org.testng.internal.Parameters.injectParameters(Parameters.java:796)
    at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:983)
    at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:125)
    at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:109)
    at org.testng.TestRunner.privateRun(TestRunner.java:648)
    at org.testng.TestRunner.run(TestRunner.java:505)

Как побочный эффект этого , Я не могу имитировать методы stati c класса util при написании BDD. Я новичок в огурце BDD. Любая помощь / указатели приветствуются.

1 Ответ

1 голос
/ 06 мая 2020

Получив некоторую помощь по root причине из канала # help-cucumber-jvm slack, я смог root вызвать его для тестированияng + powermock с поставщиками данных с использованием настраиваемых классов. Например, этот тест не проходит

import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.testng.PowerMockTestCase;
import org.testng.Assert;
import org.testng.annotations.DataProvider;
import org.testng.annotations.ObjectFactory;
import org.testng.annotations.Test;

import java.io.IOException;
import java.util.concurrent.TimeUnit;
import static org.mockito.Matchers.any;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectWriter;

@PrepareForTest(Util2.class)
public class TestngWithDataproviderTestngTest extends PowerMockTestCase {

    @ObjectFactory
    public org.testng.IObjectFactory getObjectFactory() {
        return new org.powermock.modules.testng.PowerMockObjectFactory();
    }

    private void mockActiveBucket() {
        PowerMockito.mockStatic(Util.class);
        PowerMockito.when(Util.getBucketId(any(Long.class))).thenReturn(3);
    }

    @Test(dataProvider = "users")
    public void testMockStatic(MyTestCaseImpl myTestCase) {
        System.out.println("myTestCase: " + myTestCase);
        System.out.println("static test passed");
        mockActiveBucket();
        Assert.assertTrue(true);
    }

    @DataProvider(name = "users")
    public Object[][] users() {
        return new Object[][]{{new MyTestCaseImpl(5)}};
    }
}

//interface MyTestCase {
//}

class MyTestCaseImpl { //implements MyTestCase{
    int i;

    public MyTestCaseImpl() {
    }

    public MyTestCaseImpl(int i) {
        this.i = i;
    }

    public int getI() {
        return i;
    }

    public void setI(int i) {
        this.i = i;
    }
}

class Util2 {
    public static int getBucketId(long eventTimestamp) {
        Long minsPast5MinBoundary = (eventTimestamp % TimeUnit.MINUTES.toMillis(5)) / TimeUnit.MINUTES.toMillis(1);
        return minsPast5MinBoundary.intValue();
    }
}

Здесь, как уже упоминалось, кажется, что это известная проблема с обходным путем. Надеюсь, это поможет.

...