所以我的班级中有一个静态变量。我试图用Powermockito来嘲笑它,但我收到了错误。
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.2.3/jquery.min.js"></script>
<div>
<div class="img-wrapper"></div>
</div>
我的测试类是这样的:
public class ClassUnderTest{
private static EntityManager em = AppEntityManager.createEntityManager();
public static String methodUnderTest(){
// this method dosent use EntityManager em
}
}
@RunWith(PowerMockRunner.class)
@PrepareForTest({ AppEntityManager.class, ClassUnderTest.class })
public class ClassUnderTestTest {
@Mock
private EntityManager emMock;
@InjectMocks
private ClassUnderTest feMock;
static ClassUnderTest fe = new ClassUnderTest();
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
}
@Test
public void test() {
PowerMockito.mockStatic(ClassUnderTest.class);
PowerMockito.mockStatic(AppEntityManager.class);
Mockito.when(AppEntityManager.createEntityManager()).thenReturn(emMock);
String s = ClassUnderTest.methodUnderTest(myParams);
// assertEquals(prams[i][1], s);
System.out.println(s);
}
}
你能告诉我哪里出错吗?
我只想测试Feb 22, 2018 9:37:31 AM oracle.jdbc.driver.OracleDriver registerMBeans
SEVERE: Error while registering Oracle JDBC Diagnosability MBean.
java.lang.LinkageError: loader constraint violation: loader (instance of org/powermock/core/classloader/MockClassLoader) previously initiated loading for a different type with name "javax/management/MBeanServer"
,那么有什么方法可以阻止methodUnderTest()
的静态初始化?
答案 0 :(得分:1)
通过实践更好的设计原则。
你能告诉我哪里出错了吗?
紧密耦合到该静态依赖项现在使您的代码难以测试。
使其成为通过构造函数注入的显式依赖项。
public class ClassUnderTest{
private EntityManager em;
public ClassUnderTest(EntityManager em) {
this.em = em;
}
public String methodUnderTest(){
// this method dosent use EntityManager em
}
}
现在测试时,您可以简单地传递空EntityManager
,因为测试中不需要它。
答案 1 :(得分:1)
此代码适用于我
@RunWith(PowerMockRunner.class)
@PrepareForTest({ AppEntityManager.class})
public class ClassUnderTestTest {
@Mock
private EntityManager emMock;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
}
@Test
public void test() {
PowerMockito.mockStatic(AppEntityManager.class);
Mockito.when(AppEntityManager.createEntityManager()).thenReturn(emMock);
String s = ClassUnderTest.methodUnderTest(myParams);
// assertEquals(prams[i][1], s);
}
}
一些要点
@Aurowired
,因此不需要@InjectMocks
。 ClassUnderTest::methodUnderTest
下的代码,因此请勿在{{1}}中使用ClassUnderTest @PrepareForTest
说完所有这些。您应该认真考虑重构代码以最小化(如果可能消除)所有静态方法和字段。
答案 2 :(得分:0)
使用PowerMockito.when
代替Mockito.when
。
并移除mockStatic
的{{1}}。
所以:
ClassUnderTest
答案 3 :(得分:0)
正如许多其他已经提到的那样,你真的不应该使用静态依赖,因为它会导致那种可怕的可测试设计。
但是,如果您无法更改测试中的代码,则可以通过反射注入EntityManager:
public class ClassUnderTestTest {
private ClassUnderTest classUnderTest;
@BeforeEach
public void setUp() throws Exception {
final Field entityManagerField;
classUnderTest = new ClassUnderTest();
//Use getDeclaredField(...) since field is private
entityManagerField = classUnderTest.getClass()
.getDeclaredField("em");
//Set accessible since field is private
entityManagerField.setAccessible(true);
entityManagerField.set(classUnderTest,
Mockito.mock(EntityManager.class));
}
@Test
public void test() {
String s = classUnderTest.methodUnderTest();
// assertEquals(prams[i][1], s);
System.out.println(s);
}
}
class ClassUnderTest{
private static EntityManager em;
public String methodUnderTest(){
// this method dosent use EntityManager em
// but solution don´t care
return "";
}
}
这样你也可以关闭Pandora's Box又名PowerMock并继续进行基本的UnitTesting和嘲笑。