I just upgraded to Mockito v 1.10.18 (using JUnit 4.12 and PowerMock 1.6.2). This used to work …
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration({ "classpath:test-context.xml" })
#DirtiesContext(classMode = ClassMode.AFTER_CLASS)
#FixMethodOrder(MethodSorters.NAME_ASCENDING)
#PrepareForTest( Transport.class )
public class AccessCodeServiceIT
{
#Rule
public PowerMockRule rule = new PowerMockRule();
…
#Autowired
private EmailService m_emailSvc;
#Before
public final void setup()
{
final EmailService emailSvcSpy = (EmailService) Mockito.spy(getTargetObject(m_emailSvc));
but now with the new version of Mockito, I get the following exception on the above line …
findAccessCodeByCode(org.mainco.subco.ecom.service.AccessCodeServiceIT) Time elapsed: 1.588 sec <<< ERROR!
java.lang.ClassCastException: org.mainco.subco.email.service.EmailServiceImpl cannot be cast to java.lang.Class
at org.mainco.subco.ecom.service.AccessCodeServiceIT.setup(AccessCodeServiceIT.java:103)
Related
It seems pass when a run the test individually but fine when fair when running the class .I have tried to use #Before and #After annotatoon.And only the Dirtiescontext most fit my case.My question is any alternative for dirtiescontext(too slow) or any method can suit my case?
My test code:
#SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
//#DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD)
#AutoConfigureMockMvc
class UserCoreControllerTest {
#Autowired
private UserRepository userRepository;
#Autowired
private UserCoreService userCoreService;
#Autowired
private ObjectMapper objectMapper;
#Autowired
private MockMvc mockMvc;
/*
*//* #BeforeTestMethod
public void setUp(){
System.out.println("begin");
userRepository.save(mockUser());
}
#AfterTestMethod
public void tearOff(){
System.out.println("end");
userRepository.deleteById(1);
}
*/
private User mockUser(){
User user= new User(0,"admin","admin",null,null,"yl","sd"
,"434","dsf",null,4,2,new ArrayList<>());
user.getApplications().add(mockJobOrder("job1title","b"));
user.getApplications().add(mockJobOrder("job2title","d"));
return user;
}
private JobOrder mockJobOrder(String title,String des){
return new JobOrder(0,1,title,des,null,null,0,2,false,0,null);
}
#Test
void getProfile() throws Exception {
userRepository.save(mockUser());
mockMvc.perform(get("/UserJob/getProfile/{id}", 1)
.accept(MediaType.APPLICATION_JSON_VALUE)
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.username")
.value("admin"))
.andDo(print());
}
#Test
void getUserByName() throws Exception {
userRepository.save(mockUser());
mockMvc.perform(get("/UserJob/get/Byusername/{username}", "admin")
.accept(MediaType.APPLICATION_JSON_VALUE)
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.password").value("admin"));
//if cant found user
MvcResult whatever = mockMvc.perform(get("/UserJob/get/Byusername/{username}", "whatever")
.accept(MediaType.APPLICATION_JSON_VALUE)
)
.andExpect(status().isOk())
.andReturn();
Assertions.assertEquals("",whatever.getResponse().getContentAsString());
}
#Test
void updateUser() throws Exception {
userRepository.save(mockUser());
User updated=new User(1,"alex","admin",null,null,"yl","sd"
,"434","dsf",null,4,2,null);
String request=objectMapper.writeValueAsString(updated);
MvcResult mvcResult=mockMvc.perform(MockMvcRequestBuilders.put("/UserJob/updateuser")
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON_VALUE)
.content(request)
)
.andExpect(status().isOk())
.andDo(print())
.andReturn();
Assertions.assertEquals("Successful update",mvcResult.getResponse().getContentAsString());
mockMvc.perform(get("/UserJob/getProfile/{id}", 1)
.accept(MediaType.APPLICATION_JSON_VALUE)
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.username")
.value("alex"))
.andDo(print());
}
#Test
void showApplicationshistory() throws Exception {
userRepository.save(mockUser());
mockMvc.perform(get("/UserJob/application/history/{id}", 1)
.accept(MediaType.APPLICATION_JSON_VALUE)
)
.andExpect(status().isOk())
.andExpect(jsonPath("$[0].title").value("job1title"))
.andExpect(jsonPath("$[1].title").value("job2title"))
.andDo(print());
}
#Test
void addUser() throws Exception {
User user=mockUser();
user.setUsername("tom");
String request=objectMapper.writeValueAsString(user);
mockMvc.perform(MockMvcRequestBuilders.post("/UserJob/add/user")
.contentType(MediaType.APPLICATION_JSON)
.content(request)
.accept(MediaType.APPLICATION_JSON_VALUE))
.andExpect(status().isOk())
.andExpect(jsonPath("$.username").value("tom"));
}
Application properties(i test it on a real database with drop-create)
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.username=*
spring.datasource.password=*
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.defer-datasource-initialization=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
spring.sql.init.mode=always
logging.level.root=INFO
I guess that the test are failing because of some user constraints - since you insert the user a multiple times here.
There are multiple solutions for that.
Mark your test as transactional. The transaction is automatically rollbacked for tests.
Clear the tables manually after/before each test. Either by using the repository.deleteAll() or truncate the whole db with some sql statements.
Just as a side information: You can also use testcontainers instead of having a persistente database locally. See https://www.testcontainers.org/ or even better: a wrapper library around it: https://github.com/PlaytikaOSS/testcontainers-spring-boot
I want to test 2 static methods in Android app. So I use PowerMock for this.
I write 2 tests. One unit test and one instrumented unit test.
My android build.gradle:
dependencies {
androidTestCompile "org.mockito:mockito-android:2.7.21"
androidTestCompile "org.powermock:powermock-api-mockito:1.6.6"
androidTestCompile 'org.powermock:powermock-module-junit4:1.6.6'
testCompile 'junit:junit:4.12'
testCompile 'org.powermock:powermock-api-mockito:1.6.6'
testCompile 'org.powermock:powermock-module-junit4:1.6.6'
}
Unit test is in folder: app/src/test/java/com/mycompany/StringUtilTest.java
Here code:
#RunWith(PowerMockRunner.class)
#PrepareForTest(StringUtil.class)
public class StringUtilTest {
#Test
public void isCorrectEmailStub() {
// mock all the static methods in a class called "StringUtil"
mockStatic(StringUtil.class);
String INCORRECT_EMAIL_TO_CHECK = "incorrect_email_some.com";
when(StringUtil.isCorrectEmail(INCORRECT_EMAIL_TO_CHECK)).thenReturn(true);
assertThat(StringUtil.isCorrectEmail(INCORRECT_EMAIL_TO_CHECK), is(true));
}
}
And it work fine. OK.
Instrumented unit test is in folder: app/src/androidTest/java/com/mycompany/StringUtilInstrumentedTest.java
Here code:
#RunWith(PowerMockRunner.class)
#PrepareForTest(StringUtil.class)
public class StringUtilInstrumentedTest {
private static String TAG;
private Context context;
#Before
public void init() {
TAG = StringUtilInstrumentedTest.class.getName();
context = InstrumentationRegistry.getTargetContext();
}
#Test
public void decliningAge() {
// mock all the static methods in a class called "StringUtil"
mockStatic(StringUtil.class);
// use Mockito to set up your expectation
String expected = "first";
when(StringUtil.decliningAge(context, 1)).thenReturn(expected);
assertThat(StringUtil.decliningAge(context, 1), is(expected));
}
}
But when I run this test I get error:
java.lang.ClassNotFoundException: com.mycompany.StringUtilInstrumentedTest
at java.lang.Class.classForName(Native Method)
at java.lang.Class.forName(Class.java:324)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1879)
Caused by: java.lang.IllegalStateException: Failed to transform class with name com.mycompany.StringUtilInstrumentedTest.Reason: com.mycompany.StringUtilInstrumentedTest
at org.powermock.core.classloader.MockClassLoader.loadMockClass(MockClassLoader.java:284)
at org.powermock.core.classloader.MockClassLoader.loadModifiedClass(MockClassLoader.java:192)
at org.powermock.core.classloader.DeferSupportingClassLoader.loadClass1(DeferSupportingClassLoader.java:77)
at org.powermock.core.classloader.DeferSupportingClassLoader.loadClass(DeferSupportingClassLoader.java:67)
at java.lang.ClassLoader.loadClass(ClassLoader.java:469)
Caused by: javassist.NotFoundException: com.mycompany.StringUtilInstrumentedTest
at javassist.ClassPool.get(ClassPool.java:452)
at org.powermock.core.classloader.MockClassLoader.loadMockClass(MockClassLoader.java:262)
I am new to JUNITS and have been trying to use Mockito and PowerMockito for writing some test cases for my code but have been facing an issue.
Class Code:
public class Example implements Callable<Void> {
int startIndex;
int endIndex;
ConnectionPool connPool;
Properties properties;
public Example(int start, int end,
ConnectionPool connPool, Properties properties) {
this.startIndex = start;
this.endIndex = end;
this.connPool= connPool;
this.properties = properties;
}
#Override
public Void call() throws Exception {
long startTime = System.currentTimeMillis();
try {
List<String> listInput = new ArrayList<>();
Service service = new Service(
dbConnPool, properties, startIndex, endIndex);
service.getMethod(listInput);
.
.
.
JUNIT Code:
#RunWith(PowerMockRunner.class)
#PrepareForTest()
public class ExampleTest {
#Mock
private ConnectionPool connectionPool;
#Mock
private Properties properties;
#Mock
private Service service = new Service(
connectionPool, properties, 1, 1);
#Mock
private Connection connection;
#Mock
private Statement statement;
#Mock
private ResultSet resultSet;
#InjectMocks
private Example example = new Example(
1, 1, connectionPool, properties);
#Test
public void testCall() throws Exception {
List<String> listInput= new ArrayList<>();
listInput.add("data1");
when(service.getMethod(listInput)).thenReturn(listInput);
example.call();
}
Question: How to mock Service class and its method, getMethod, call ?
Explanation: The Service class has method getMethod, which is interacting with the DB. So, as I am not able to mock this method, the code goes through and then I have to mock all the objects in the getMethod as connection, resultset etc. else it throws NullPointerException.
Please help me understand what I am doing wrong and if possible provide your guidance on the way I should approach the JUNITS for this kind of method call.
Mockito won't help you to mock an object if you have calling of new Service inside of your method.
Instead you need to use PowerMock.expectNew
Service mockService = PowerMock.createMock(Service.class);
PowerMock.expectNew(Service.class, connectionPool, properties, 1, 1)
.andReturn(mockService);
PowerMock.replay(mockService);
For PowerMockito there is an equivalent:
PowerMockito.whenNew(Service.class)
.withArguments(connectionPool, properties, 1, 1)
.thenReturn(mockService);
Please check this article.
I am trying to work with PowerMock, over Mockito; as I loved the API's for whennew() and verifyprivate() but i have some problem when trying to run testsuites with Categories TestRunner in Junit.
For using default JUnit test runners, I created a TestCase and added PowerMockRule as instance field with #Rule annotation. While execution of tests worked like this, ExpectedException TestRule is not working when used in conjunction
Example Code
#PowerMockIgnore ("*")
#PrepareForTest (CustomizedSSHConnection.class)
public class TestExpectedExceptionRule {
private Connection connection;
private ConnectionInfo connectionInfo;
#Rule
public PowerMockRule rule = new PowerMockRule ();
#Rule
public ExpectedException exception = ExpectedException.none ();
#Test
public void testExcepitonWithPowerMockRule() {
exception.expect (NullPointerException.class);
exception.expectMessage ("Image is null");
throw new NullPointerException ("Image is null");
}
}
Instead of using #Rule PowerMockRule if I use #RunWith(PowerMockRunner.class) this testcase will pass.
One other observation is if I annotate PowerMockRule with #ClassRule this succeeds but some of the mocking methods throwing exceptions.
PowerMock creates a deep clone of the TestExpectedExceptionRule object. Because of this it is running the test with a new ExpectedException rule, but you're calling exception.expect (NullPointerException.class) on the original rule. Hence the test fails, because the clone of the ExpectedException rule doesn't expect an exception.
Nevertheless there are at least two solutions for your problem.
RuleChain
Order the rules with JUnit's RuleChain. This needs some additional ugly code, but it works.
private ExpectedException exception = ExpectedException.none ();
private PowerMockRule powerMockRule = new PowerMockRule();
#Rule
public TestRule ruleChain = RuleChain.outerRule(new TestRule() {
#Override
public Statement apply(Statement base, Description description) {
return powerMockRule.apply(base, null, description);
}
}).around(exception);
Fishbowl
If you are using Java 8 then you can replace the ExpectedException rule with the Fishbowl library.
#Test
public void testExcepitonWithPowerMockRule() {
Throwable exception = exceptionThrownBy(
() -> throw new NullPointerException ("Image is null"));
assertEquals(NullPointerException.class, exception.getClass());
assertEquals("Image is null", exception.getMessage());
}
Without Java 8, you have to use an anonymous class.
#Test
public void fooTest() {
Throwable exception = exceptionThrownBy(new Statement() {
public void evaluate() throws Throwable {
throw new NullPointerException ("Image is null");
}
});
assertEquals(NullPointerException.class, exception.getClass());
assertEquals("Image is null", exception.getMessage());
}
I was able to fix this using the expected attribute in the #Test annotation. But the problem with this approach is that am unable to assert the exception message. Which is fine for me for now.
#PowerMockIgnore ("*")
#PrepareForTest (CustomizedSSHConnection.class)
public class TestExpectedExceptionRule {
private Connection connection;
private ConnectionInfo connectionInfo;
#Rule
public PowerMockRule rule = new PowerMockRule ();
#Rule
public ExpectedException exception = ExpectedException.none ();
#Test(expected = NullPointerException.class)
public void testExcepitonWithPowerMockRule() {
throw new NullPointerException ("Image is null");
}
}
I solved this problem by creating a PowerMockTestUtil class that uses a FunctionalInterface.
Utility class:
/**
* Utility class to provide some testing functionality that doesn't play well with Powermock out
* of the box. For example, #Rule doesn't work well with Powermock.
*/
public class PowerMockTestUtil {
public static void expectException(RunnableWithExceptions function, Class expectedClass, String expectedMessage) {
try {
function.run();
fail("Test did not generate expected exception of type " + expectedClass.getSimpleName());
} catch (Exception e) {
assertTrue(e.getClass().isAssignableFrom(expectedClass));
assertEquals(expectedMessage, e.getMessage());
}
}
#FunctionalInterface
public interface RunnableWithExceptions<E extends Exception> {
void run() throws E;
}
}
Sample test:
#Test
public void testValidateMissingQuantityForNewItem() throws Exception {
...
expectException(() -> catalogEntryAssociationImporter.validate(line),
ImportValidationException.class,
"Quantity is required for new associations");
}
Iam working on mockito testcases positive test methods are getting executed but comming to Exception Test methods its failing with the Exception
java.lang.Exception: Unexpected exception, expected<com.apple.ist.retail.xcard.common.exception.InvalidArgumentException> but was<org.jboss.resteasy.client.ClientResponseFailure>
at
Below is the test method which is failing and its parent class containing client object
package com.apple.ist.retail.xcard.ws.exception;
public class TestActivatePrepaidCard extends CertificateResourceTestCase {
public TestActivatePrepaidCard(String aMediaType) {
super(aMediaType);
}
#Before
public void setUp() {
super.setUp();
}
#Test(expected = InvalidArgumentException.class)
public void testActivatePrepaidCard_InvalidArgumentException()
throws DuplicateCertificateIDException, InvalidArgumentException,
DupTxnRefException, AmountException, SystemException,
XCardException {
when(
server.activatePrepaidCard(any(DiagnosticContext.class),
any(String.class), any(Number.class),
any(Amount.class), any(String.class), any(int.class),
any(HashMap.class), any(String.class),
any(SalesOrg.class), any(TxnRef.class))).thenThrow(
new InvalidArgumentException("Invalid Argument ",
INVALID_ARGUMENT));
client.activatePrepaidCard(certificateRequest);
}
Its failing near client.activatePrepaidCard(certificateRequest); with ClientResponseFailure Exception
Parent test case is
package com.apple.ist.retail.xcard.ws.exception;
#RunWith(value = Parameterized.class)
public abstract class CertificateResourceTestCase extends Assert {
protected CertificateResource client;
protected XCardServiceServer server;
protected CertificateResource resource;
protected CertificateRequest certificateRequest;
// protected Dispatcher dispatcher = MockDispatcherFactory.createDispatcher();
private String mediaType;
public CertificateResourceTestCase(String aMediaType) {
this.mediaType = aMediaType;
server = mock(XCardServiceServer.class);
CertificateResourceImpl xcardServiceRs = new CertificateResourceImpl();
xcardServiceRs.setService(server);
Dispatcher dispatcher = MockDispatcherFactory.createDispatcher();
dispatcher.getRegistry().addSingletonResource(xcardServiceRs);
dispatcher.getProviderFactory().addExceptionMapper(
XCardExceptionMapper.class);
dispatcher.getProviderFactory().addExceptionMapper(
BusinessExceptionMapper.class);
dispatcher.getProviderFactory().addExceptionMapper(
RuntimeExceptionMapper.class);
dispatcher.getProviderFactory().addExceptionMapper(
BusinessExceptionMapper.class);
dispatcher.getProviderFactory().addExceptionMapper(
RuntimeExceptionMapper.class);
dispatcher.getProviderFactory()
.getServerMessageBodyWriterInterceptorRegistry()
.register(new XCardTxnWriterInterceptor());
dispatcher.getProviderFactory().getContextDataMap()
.put(HttpServletRequest.class, new MockHttpServletRequest());
client = ProxyFactory.create(CertificateResource.class, "/", new InMemoryClientExecutor(dispatcher));
diagnosticContext.setReportingRecommended(false);
}
#After
public void tearDown() throws Exception {
Mockito.reset(server);
}
Please let me know whats wrong in my code,I am pasting complete code so that I will not miss any detail
Your code is throwing an ClientResponseFailure. Debug your test and find out why. Use an exception breakpoint.