当前位置: 首页 > 知识库问答 >
问题:

用PowerMockTestCase Cucumber testng模拟静态类

傅英喆
2023-03-14

我正在使用cucumber BDD,testng,java编写一些BDD测试。为了编写我的测试,我想模拟静态类。然而,当我编写这个testrunner时,它无法初始化BDD场景。

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();
    }
}
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)

这样做的一个副作用是,我无法在编写BDD时模拟util类的静态方法。我对cucumberBDD是新手。任何帮助/指针都是感激的。

共有1个答案

申屠俊发
2023-03-14

在从#help-cucumber-jvm slack channel获得了一些根原因方面的帮助之后,我能够通过使用自定义类的dataproviders将根原因引入TestNG+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();
    }
}

正如所提到的,这似乎是一个已知的问题,有一个解决方案。希望这能有所帮助。

 类似资料:
  • 问题内容: 我对Java的座右铭是“仅仅因为Java具有静态块,并不意味着您应该使用它们。” 除了笑话,Java中还有许多使测试成为噩梦的技巧。我最讨厌的两个是匿名类和静态块。我们有很多使用静态块的遗留代码,这些是我们编写单元测试时最讨厌的点之一。我们的目标是能够以最小的代码更改为依赖于此静态初始化的类编写单元测试。 到目前为止,我对同事的建议是将静态块的主体移到私有的静态方法中并对其进行调用。然

  • 在安装到AEM 5.6.1实例之前,我正在使用maven构建和测试我的代码。我已经编写了单元测试,这些测试使用wcm的实现从aem模拟中获益。io和其他需要使用powermockito模拟静态方法的单元测试。 以下是我对aem上下文、sling Mock和powermock的maven依赖关系。 在我的课堂上,我正在为aem上下文设置规则,并准备一些用于模拟的静态类: 当我通过命令行运行mvn测试

  • 问题内容: 我已经写了一家工厂来生产物体: 我想验证传递给的参数,但不知道如何模拟静态方法。我在测试用例中使用的是和。有没有模拟或验证此特定用例的好方法? 问题答案: 在Mockito上使用PowerMockito。 示例代码:

  • 我有一堂这样的课: 我需要使用EasyMock模拟服务<代码>EasyMock。createMock()后跟replay()不起作用。P、 S:这是其他开发人员编写的遗留代码,我们不能在这里更改代码。

  • 问题内容: 我的代码中有一个静态方法,希望以某种方式进行模拟。 我正在使用jmock。 我想可以做到这一点的一种方法是在静态方法周围设置“包装类”并模拟该方法,但是我希望有一个更好的解决方案。 我要用这种错误的方式? 反馈: 我将要有一个接口和一个类,该接口和类具有一个仅称为静态方法的方法。这将允许我通过仅模拟对此包装器类的调用来模拟逻辑。(即使谈论它我也觉得很脏:)) 问题答案: 我们不支持在j

  • 我正在尝试使用JUnit、Mockito和PowerMock验证对的调用。 下面是我的测试用例: 下面是测试中的代码: 非常有趣的是,这段代码失败时出现: