Suppose that I have a class like;
public class FooBar {
public int getMethod(List<String> code){
if(code.size() > 100)
throw new Exception;
return 0;
}
}
and I have a test class like this;
@RunWith(PowerMockRunner.class)
@PrepareForTest(FooBar.class)
public class FooBarTest{
FooBar fooBarInstance;
@Before
public void setUp() {
//MockitoAnnotations.initMocks(this);
fooBarInstance = new FooBar();
}
@Test(expected = Exception.class)
public void testGetCorrelationListCodesParameter() {
List<String> codes = Mockito.spy(new ArrayList<String>());
Mockito.doReturn(150).when(codes).size();
fooBarInstance.getMethod(codes);
}
}
How can I make this test method to throw an exception ? I've dealing for hours to do this. Well thanks anyway.
Spying is not needed, mocking is enough. As @David said, also mocking is not needed and not recommended for value object.
Using @Test(expected = Exception.class)
has many drawbacks, test can pass when exception is thrown from not expected places. Test is not working but is visible as green.
I prefer BDD style testing with catch-exception .
Reasons for using catch-exceptions
(...) in comparison to the use of try/catch blocks.
- The test is more concise and easier to read.
- The test cannot be corrupted by a missing assertion. Assume you forgot to type fail() behind the method call that is expected to throw an exception.
(...) in comparison to test runner-specific mechanisms that catch and verify exceptions.
- A single test can verify more than one thrown exception.
- The test can verify the properties of the thrown exception after the exception is caught.
- The test can specify by which method call the exception must be thrown.
- The test does not depend on a specific test runner (JUnit4, TestNG).
import static com.googlecode.catchexception.CatchException.caughtException;
import static com.googlecode.catchexception.apis.CatchExceptionAssertJ.*;
public class FooBarTest {
FooBar sut = new FooBar(); // System Under Test
@Test
public void shouldThrowExceptionWhenListHasTooManyElements() {
when(sut).getMethod(listWithSize(150));
then(caughtException()).isInstanceOf(Exception.class);
}
private List<String> listWithSize(int size) {
return new ArrayList<String>(Arrays.asList(new String[size]));
}
}
Full working code for this test: https://gist.github.com/mariuszs/8543918
Not recommended solution with expected
and mocking.
@RunWith(MockitoJUnitRunner.class)
public class FooBarTest {
@Mock
List<String> codes;
FooBar fooBarInstance = new FooBar();
@Test(expected = Exception.class)
public void shouldThrowExceptionWhenListHasTooManyElements() throws Exception {
when(codes.size()).thenReturn(150);
fooBarInstance.getMethod(codes);
}
}
A list is a value object. It's not something we should mock. You can write this whole test without mocking anything, if you're prepared to build a list that has a size in excess of 100.
Also, I prefer to use JUnit's ExpectedException
mechanism, because it lets you check which line of the test method threw the exception. This is better than passing an argument to the @Test
annotation, which only lets you check that the exception was thrown somewhere within the method.
public class FooBarTest {
@Rule
public ExpectedException exceptionRule = ExpectedException.none();
private FooBar toTest = new FooBar();
@Test
public void getMethodThrowsException_whenListHasTooManyElements() {
List<String> listWith101Elements =
new ArrayList<String>(Arrays.asList(new String[101]));
exceptionRule.expect(Exception.class);
toTest.getMethod(listWith101Elements);
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.