我正在使用PowerMockito和Mockito来模拟几个静态类.我想获得在运行时调用特定模拟对象的次数,以便我可以在另一个模拟对象的验证时间中使用该计数.
我需要这个,因为我正在测试的方法启动一个线程并在一秒钟后停止线程.我的嘲笑在这1秒内被召唤好几次.调用第一个模拟后,可以调用代码分支和不同的模拟.所以,我想比较第一次模拟的计数和其他模拟的计数.
这是遗留代码.所以我无法对实际代码进行更改.我只能更改测试代码.
我正在尝试测试一个使用带有许多静态方法的计算器类的类.我以类似的方式成功地嘲笑了另一个班级,但是这个班级更加顽固.
似乎如果mocked方法包含对传入的参数之一的方法调用,则静态方法不会被模拟(并且测试中断).删除内部呼叫显然不是一种选择.有什么明显的东西我在这里不见了吗?
这是一个浓缩版本,行为方式相同......
public class SmallCalculator {
public static int getLength(String string){
int length = 0;
//length = string.length(); // Uncomment this line and the mocking no longer works...
return length;
}
}
Run Code Online (Sandbox Code Playgroud)
这是测试......
import static org.junit.Assert.assertEquals;
import static org.mockito.BDDMockito.given;
import static org.mockito.Matchers.any;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import com.solveit.aps.transport.model.impl.SmallCalculator;
@RunWith(PowerMockRunner.class)
@PrepareForTest({ SmallCalculator.class})
public class SmallTester {
@Test
public void smallTest(){
PowerMockito.spy(SmallCalculator.class);
given(SmallCalculator.getLength(any(String.class))).willReturn(5);
assertEquals(5, SmallCalculator.getLength(""));
}
}
Run Code Online (Sandbox Code Playgroud)
似乎对这个问题存在一些困惑,所以我设计了一个更"现实"的例子.这个添加了一个间接级别,因此我似乎没有直接测试模拟方法.SmallCalculator类保持不变:
public class BigCalculator {
public int getLength(){ …Run Code Online (Sandbox Code Playgroud) 我有以下代码从DB获取当前计数器值.然后它更新DB中的计数器,然后再次检索该值.
int current = DBUtil.getCurrentCount();
DBUtil.updateCount(50);// it updates the current count by adding 50
int latest = DBUtil.getCurrentCount();
Run Code Online (Sandbox Code Playgroud)
我想以这样的方式模拟静态方法,即第一个调用应返回100,第二个调用应返回150.如何使用PowerMockito实现此目的?我正在使用TestNG,Mockito和PowerMock.
我需要使用PowerMockito来测试是否调用了特定的静态方法.我使用以下PowerMockito和JUnit库...
我在让PowerMockito.verifyStatic()方法正常工作时遇到问题.在下面的代码示例中,我尝试使用@PrepareForTest和mockStatic(),并尝试排除它们.在代码示例中,我包含它们.
测试类:
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(PowerMockRunner.class)
@PrepareForTest(Test1.class)
public class PowerMockTest {
@Test
public void staticVerifyTest() {
PowerMockito.mockStatic(Test1.class);
// Test
PowerMockito.verifyStatic();
//Test1.staticMethod();
}
}
Run Code Online (Sandbox Code Playgroud)
被测试类:
public class Test1 {
public static void staticMethod() {
System.out.println("Static Method!");
}
}
Run Code Online (Sandbox Code Playgroud)
测试在运行时通过,但它应该失败,因为从不调用Test1.staticMethod().任何有关这方面的帮助将不胜感激!
我正在尝试模拟 KeyStore 类。模拟之后,我不希望加载方法被调用时发生任何事情。因此我编写了以下几行来实现这一目标。
@PrepareForTest(KeyStoreFactory.class)
@Test
public void should_verify_signature_when_verifySignature_called_with_fileName_and_certificate_details_in_verifySignature_method() throws Exception {
PowerMockito.mockStatic(KeyStoreFactory.class);
KeyStore keyStoreMock = PowerMockito.mock(KeyStore.class);
PowerMockito.when(KeyStoreFactory.getInstance(anyString(), anyString())).thenReturn(keyStoreMock);
Mockito.doNothing().when(keyStoreMock).load(Mockito.any(InputStream.class), Mockito.any(char[].class));
Certificate certificateMock = Mockito.mock(Certificate.class);
when(keyStoreMock.getCertificate(anyString())).thenReturn(certificateMock);
boolean result = signatureUtil.verifySignature("src//test//java//Updates.zip.signed.pkcs7"
, "src//test//java//Updates-retrieved.zip", "Windows-MY,SunMSCAPI,someName");
Assert.assertTrue(result);
}
Run Code Online (Sandbox Code Playgroud)
但 load 方法抛出空指针异常。然后,当我调试时,我发现真正的方法正在被调用,尽管我已经指定了mockito不要这样做。我在这里做错了什么?请指教。
以下是我编写测试的方法。
@Override
public boolean verifySignature(String filePath, String extractContentsPath, String csvParams)
throws ServiceSDKException {
boolean result = false;
String typeOfCertificateStore = "";
String certificateStoreProvider = "";
String certificateName = "";
SignerInformationVerifier verifier = null;
if (filePath != null && extractContentsPath != null && csvParams …Run Code Online (Sandbox Code Playgroud) 对于我的项目,我正在尝试使用SpringBootTest编写集成测试.我有第三方静态决赛课.我试着用Power mock嘲笑它.但是当尝试使用它@SpringBootTest时,抛出异常.
这是我的示例代码
@RunWith(PowerMockRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, classes = SpringTestConfig.class
@PowerMockRunnerDelegate(SpringRunner.class)
@PrepareForTest(IdGenerator.class)
public class RestTestIT
{
@Before
public void setUp() throws Exception
{
PowerMockito.mockStatic(IdGenerator.class);
}
..
}
Run Code Online (Sandbox Code Playgroud)
组态:
@Configuration
@EnableAutoConfiguration
@ComponentScan("com.xx.yy.zz")
public class SpringTestConfig
{
}
Run Code Online (Sandbox Code Playgroud)
抛出异常:
2016-09-01 11:35:50.945 ERROR 18649 --- [ main] o.s.boot.SpringApplication : Application startup failed
java.lang.IllegalArgumentException: Cannot find class [com.xx.yy.zz.SpringTestConfig$$EnhancerBySpringCGLIB$$414ee08e]
at org.springframework.util.ClassUtils.resolveClassName(ClassUtils.java:287) ~[na:4.3.2.RELEASE]
at org.springframework.boot.test.mock.mockito.MockitoPostProcessor.getConfigurationClasses(MockitoPostProcessor.java:147) ~[na:1.4.0.RELEASE]
at org.springframework.boot.test.mock.mockito.MockitoPostProcessor.postProcessBeanFactory(MockitoPostProcessor.java:132) ~[na:1.4.0.RELEASE]
at org.springframework.boot.test.mock.mockito.MockitoPostProcessor.postProcessBeanFactory(MockitoPostProcessor.java:126) ~[na:1.4.0.RELEASE]
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:284) ~[na:4.3.2.RELEASE]
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:174) ~[na:4.3.2.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:681) ~[na:4.3.2.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:523) ~[na:4.3.2.RELEASE]
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122) …Run Code Online (Sandbox Code Playgroud) 我有以下测试......
import org.scalatest.junit.JUnitRunner
...
@PowerMockRunnerDelegate(classOf[JUnitRunner])
@PrepareForTest(Array(classOf[AuditLog]))
class ConnectorAPITest extends path.FreeSpec with ShouldMatchers {
"Mocked Tests" - {
println("This got called in the mocked tests.")
PowerMockito.mockStatic(classOf[AuditLog]);
...
}
}
Run Code Online (Sandbox Code Playgroud)
但是当我跑步时,我得到......
An exception or error caused a run to abort: The class com.paxata.services.log.AuditLog not prepared for test.
To prepare this class, add class to the '@PrepareForTest' annotation.
In case if you don't use this annotation, add the annotation on class or method level.
org.powermock.api.mockito.ClassNotPreparedException:
The class com.paxata.services.log.AuditLog not prepared for test.
To …Run Code Online (Sandbox Code Playgroud) 代码部分中的下面发布的方法包含一个静态方法,即"with()".我想测试下面的代码,所以我编写了这个方法的测试,如测试部分所示.
我尝试使用"spy()"和"mock()"测试方法,但测试失败了alwyas.
请让我知道如何测试方法返回void?
码
public RequestCreator requestCreatorFromUrl(String picUrl) {
return Picasso.with(mCtx).load(picUrl);
}
Run Code Online (Sandbox Code Playgroud)
测试:
public class ValidationTest {
@Mock
private Context mCtx = null;
@Rule
public MockitoRule mockitoRule = MockitoJUnit.rule();
@Before
public void setUp() throws Exception {
mCtx = Mockito.mock(Context.class);
Assert.assertNotNull("Context is not null", mCtx);
}
@Test
public void whenRequestCreatorFromUrlTest() throws Exception {
Picasso picasso = Picasso.with(mCtx);
Picasso spyPicasso = spy(picasso);
Uri mockUri = mock(Uri.class);
RequestCreator requestCreator = Picasso.with(mCtx).load(mockUri);
RequestCreator spyRequestCreator = spy(requestCreator);
doReturn(spyRequestCreator).when(spyPicasso.load(mockUri));
//when(spyPicasso.load(mockUri)).thenReturn(spyRequestCreator);
RequestCreator actual = spyPicasso.load(mockUri);
Assert.assertEquals(requestCreator, …Run Code Online (Sandbox Code Playgroud) 这是我的设置不起作用:
SomeclassTest.java
@RunWith(PowerMockRunner.class)
@PowerMockIgnore("javax.management.*")
@PrepareForTest({SomeclassTest.class, Someclass.class})
public class SomeclassTest{
@InjectMocks
private Someclass someclass;
@Test(expected=None.class)
public void testRun() throws Exception{
PowerMockito.mockStatic(Thread.class);
PowerMockito.doThrow(new RuntimeException()).when(Thread.class);
Thread.sleep(Matchers.anyLong());
try {
Thread.sleep(5L);
}catch(Exception ex) {
System.out.println("working"); // this is working
}
WhiteboxImpl.invokeMethod(someclass, "run"); // not working in someclass
PowerMockito.verifyStatic();
}
Run Code Online (Sandbox Code Playgroud)
某个类.java
@Named("Someclass")
public class Someclass extends Thread{
@Override
public void run() {
while (true) {
try {
// clear interruption
interrupted();
long noOfRec= 0;
if (noOfRec> 0) {
Thread.sleep(shortInterval);
} else {
Thread.sleep(longInterval);
}
} catch …Run Code Online (Sandbox Code Playgroud) 今天我为 java 16 预览版创建了一个小型测试项目。我创建了一个密封的接口和最终的实现。
我想知道是否有办法能够模拟密封接口,以便我可以测试使用密封接口的实现。
package gluestick;
public sealed interface Test permits TestImpl {
int doIt();
}
Run Code Online (Sandbox Code Playgroud)
package gluestick;
public final class TestImpl implements Test {
@Override
public int doIt() {
return 0;
}
}
Run Code Online (Sandbox Code Playgroud)
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
public class MyTest {
@Test
public void test() {
Mockito.mock(gluestick.Test.class);
}
}
Run Code Online (Sandbox Code Playgroud)
然而,这一切都相当于创建一个 java.lang.IncompleteClassChangeError ,因为密封类无法实现。
org.mockito.exceptions.base.MockitoException:
Mockito cannot mock this class: interface gluestick.Test.
Mockito can only mock non-private & non-final classes.
If you're not sure why you're getting this error, please …Run Code Online (Sandbox Code Playgroud) powermockito ×10
java ×6
mockito ×5
junit ×4
unit-testing ×4
mocking ×3
powermock ×3
android ×1
scala ×1
scalatest ×1
spring ×1
spring-boot ×1