I need your help to understand a unit (method) behaviors within a unit test class shown below.
public void updateAccount(Account account) {
if (!accountExists(account.getAccountNo())) {
throw new AccountNotFoundException();
}
accounts.put(account.getAccountNo(), account);
}
The method shown above tells me that the exception will be thrown if the account is not found
However the 2nd test ( updateNotExistedAccount) method shown below shows that it's expected that the method above (updateAccount ) should throw an exception to past the test. However, newAccount is already initialized /created within the createNewAccount so it exists already. So I assume that the updateNotExistedAccount will failed the test (because updateAccount won't throw exceptions in that case ), however updateNotExistedAccount passed.
public class InMemoryAccountDaoTests {
private static final String NEW_ACCOUNT_NO = "998";
private Account newAccount;
private InMemoryAccountDao accountDao;
#Before
public void init() {
newAccount = new Account(NEW_ACCOUNT_NO, 200);
accountDao = new InMemoryAccountDao();
}
#Test
public void createNewAccount() {
accountDao.createAccount(newAccount);
assertEquals(accountDao.findAccount(NEW_ACCOUNT_NO), newAccount); }
#Test(expected = AccountNotFoundException.class)
public void updateNotExistedAccount() { accountDao.updateAccount(newAccount);
}
Is it wrong if I assume updateNotExistedAccount will fail the test?
Seems like the data are persisted from one test to another.
Try to clean the data after each test.
#After
public void clean(){
// this method will be run after each single #Test method
// you can use this to clean all resoruces after a test. in your case for example
accountDao.deleteById(newAccount.getId());
}
For your test to be complete, and to test the update, I would do something like this:
#Test
public void updateExistingAccount() {
accountDao.createAccount(newAccount);
dbAccount = accountDao.findAccount(newAccount.getId);
dbAccount.setName("");
dbAccount.setSurname("");
// etc...
accountDao.updateAccount(dbAccount);
dbAccountUpdated = accountDao.findAccount(newAccount.getId);
assertEquals(accountDao.findAccount(dbAccountUpdated.getId()), dbAccount);
}
UPDATE
Consider also that #Before and #After runs respectively before and after each single test.
#BeforeClass and #AfterClass respectively before and after all tests.
With the use of these 4 methods you can start always the test with the desired dataset, and after the test clean everything as it were.
Please see:
Difference between #Before, #BeforeClass, #BeforeEach and #BeforeAll
To properly check need to look at your newAccount code as well as what all you are Mocking.
Check your #Before method as that will run before every #Test
Check if which test is running first when you run your suite
Related
I want to Run Test in a same class with two credentials, and both are in same TestRunner class, I want to declare in #Beforemethod class so that no need to write same code in Every #Test.
If I understood, You want to run same test twice, but with different credentials.
If this is the case use dataProvider:
#DataProvider(name="login")
public Object[][] getData() {
return new Object[][] {
{"test2#test.com", "test",false},
{"test#test.com", "abcabc",true}
};
}
and here is method how to call it.
#Test(dataProvider="login")
public void testLogin(String usernameEmail, String password,boolean flag) throws InterruptedException {
if(flag){
Assert.assertTrue(!errorMessage.isDisplayed());
}else{
Assert.assertTrue(errorMessage.isDisplayed());
}
}
Hope I understood and it would help You,
Updated answer with pseudo code of a sort, so You could create method without annotation just simple method inside test class or in different one, depending on Your logic, and provide parameter to that method within test methods here is example:
Don't know how You data is set in #BeforeMethod, because there is no code example, but here is something:
#Test
public void testLogin_1(){
login(email, password)
}
#Test
public void testLogin_2(){
login(email2, password2)
}
private void login(String email, String password){
inputEmail(email);
inputPassword(password);
clickSubmit();
Assert.assertEquals();
// do some asserts so if You want to assert some error cases.
}
Hope this helps,
I am having a test suite which is having the following structure
TestClass1
- testmethod1()
- testmethod2()
- testmethod3()
- testmethod4()
TestClass2
- testmethod11()
- testmethod22()
- testmethod33()
- testmethod44()
In the above structure i want to execute the testmethod4() as the final one. ie) executed at last.
There is a annotation #FixMethodOrder which executes a method in order not the testclass. Is there any mechanism to maintain order in test class and testmethod together. With the #FixMethodOrder i can execute the method by renaming the name of the test method but i can't instruct junit to execute the test class as the final one(last one).
Though quoting #Andy again -
You shouldn't care about test ordering. If it's important, you've got
interdependencies between tests, so you're testing behaviour +
interdependencies, not simply behaviour. Your tests should work
identically when executed in any order.
But if the need be to do so, you can try out Suite
#RunWith(Suite.class)
#Suite.SuiteClasses({
TestClass2.class,
TestClass1.class
})
public class JunitSuiteTest {
}
where you can either specify
#FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class TestClass1 {
#AfterClass
public void testMethod4() {
and then take care to name your method testMethod4 as such to be executed at the end OR you can also use #AfterClass which could soon be replaced by #AfterAll in Junit5.
Do take a look at Controlling the Order of the JUnit test by Alan Harder
#shiriam as #Andy Turner already pointed out, the order of your tests shouldn't come in question when running the tests.
If you have a routine that you want executed before doing any tests, you could use a static block of code in one of the classes.
Think of something like this:
class TestBootstrap {
// singleton instance
private static final instance;
private boolean initialized;
private TestBootstrap(){
this.initialized = false;
}
public static TestBootstrap getInstance(){
if (instance == null){
instance = new TestBootstrap()
}
}
public void init(){
// make the method idempotent
if (!initialzed){
// do init stuff
initialized = true;
}
}
public boolean isInitialized(){
return initialized;
}
}
Then in your tests use something like this:
class TestClass1{
#BeforeClass
public void setup(){
TestBootstrap.getInstance().init();
}
#Test
public void testmethod1(){
// assertions
}
// ....
}
class TestClass2{
#BeforeClass
public void setup(){
TestBootstrap.getInstance().init();
}
#Test
public void testmethod11(){
// assertions
}
// ...
}
By using the singleton instance for doing the setup for the tests you ensure that you perform the initialization of your test environment only once, independently of the order in which the test classes are executed.
I have created some automated tests to test an API using TestNG.
public class EndToEndTest {
private ResponseParser response;
private static String sessionId;
private static float cardCharge;
#BeforeClass
public void setUp() {
baseURI = getUri();
response = new ResponseParser();
#Test
#Parameters({"login", "username", "password"})
public void testOne(){
//send some test data into API using specific test data parameters
sessionId = response.getSessionId();
cardCharge = response.getCardCharge();
//assertion etc...
}
#Test
public void testTwo()
Request req = new Request.RequestBuider()
.withSession(sessionId)
.withCardCharge(cardCharge)
.with....etc...
}
This test is a template against which I have 10 or so individual testng xml files providing individual test data - essentially 10 tests. I am running the 10 testng xml files using 1 testng suite xml file.
When one 'test' finishes, I want the variables - 'sessionId' etc...to be reset to null. With the way I am running them, the variable values persist between the #Tests (desirable) but also at the class level, presumably because the way I am running with a suite, they remain in scope and not eligible for GC.
Is there a more elegant/robust solution than simply resetting each to null, for example in an #AfterClass method?
#AfterClass
public void tearDown(){
sessionId = null;
.....
}
yes, there is another way to perform this. You can override the #Test class and manipulate its behavior where u can set a default value for every variable being used.
please refer ;
http://www.javatpoint.com/custom-annotation
Did you have a look to the #BeforeTest and #AfterTestannotations?
See [TestNg documentation][1]
http://testng.org/doc/documentation-main.html
How can I test if a method does nothing. For example I have a static method that throws an exception if the given string-argument is null or empty (it's meant for argument-validation). Right now my tests look like this:
#Test
public void notNullOrEmpty_doesNothingIfValueIsNotNullOrEmpty() {
Require.notNullOrEmpty(Generate.randomString());
assertTrue(true); // <- this looks very ugly
}
#Test(expected = IllegalArgumentException.class)
public void notNullOrEmpty_throwsExceptionIfValueIsNull() {
Require.notNullOrEmpty(null);
}
#Test(expected = IllegalArgumentException.class)
public void notNullOrEmpty_throwsExceptionIfValueIsEmpty() {
Require.notNullOrEmpty("");
}
How can I make the first test to pass without calling assertTrue(true), there is a Assert.fail() is there something like an Assert.pass()?
EDIT:
Added missing (expected = IllegalArgumentException.class) to 3rd test
You have just to remove the assert in the first method.
#Test
public void notNullOrEmpty_doesNothingIfValueIsNotNullOrEmpty() {
Require.notNullOrEmpty(Generate.randomString());
// Test has passed
}
If the test method runs completely then it means it pass with success. Look at Eclipse junit output:
Update: as an additional comment, if you use Mockito framework you can leverage verify method to verify that a method was called X times. For instance, I used something like this:
verify(cmAlertDao, times(5)).save(any(CMAlert.class));
In your case, since you are testing static methods, then you might find useful using PowerMock which allows you to verify static methods (since Mockito doesn't). And you can use verifyStatic(...).
You should add #Test(expected = YourException.class) annotation.
Try to add to the first test:
#Test
public void notNullOrEmpty_doesNothingIfValueIsNotNullOrEmpty() {
String str = Generate.randomString();
Require.notNullOrEmpty(str);
assertNotNull(str);
}
and probably to you have better to rename it to notNullOrEmpty_doesNothingIfValueIsNotNullOrNotEmpty because you are testing it for not empty value.
A unit test must assert which is expected in the behavior of the method.
If in your specification, when your call notNullOrEmpty()no exception must be thrown when the data is valid and an exception must be thrown when the data is not valid so in your unit test you must do no assertion when the data is valid since if it doesn't success, a exception will be thrown and the test will so be in failure.
#Test
public void notNullOrEmpty_doesNothingIfValueIsNotNullOrEmpty() {
Require.notNullOrEmpty(Generate.randomString());
}
I just discovered when creating some CRUD tests that you can't set data in one test and have it read in another test (data is set back to its initialization between each test).
All I'm trying to do is (C)reate an object with one test, and (R)ead it with the next. Does JUnit have a way to do this, or is it ideologically coded such that tests are not allowed to depend on each other?
Well, for unit tests your aim should be to test the smallest isolated piece of code, usually method by method.
So testCreate() is a test case and testRead() is another. However, there is nothing that stops you from creating a testCreateAndRead() to test the two functions together. But then if the test fails, which code unit does the test fail at? You don't know. Those kind of tests are more like integration test, which should be treated differently.
If you really want to do it, you can create a static class variable to store the object created by testCreate(), then use it in testRead().
As I have no idea what version of Junit you talking about, I just pick up the ancient one Junit 3.8:
Utterly ugly but works:
public class Test extends TestCase{
static String stuff;
public void testCreate(){
stuff = "abc";
}
public void testRead(){
assertEquals(stuff, "abc");
}
}
JUnit promotes independent tests. One option would be to put the two logical tests into one #Test method.
TestNG was partly created to allow these kinds of dependencies among tests. It enforces local declarations of test dependencies -- it runs tests in a valid order, and does not run tests that depend on a failed test. See http://testng.org/doc/documentation-main.html#dependent-methods for examples.
JUnit is independent test. But, If you have no ways, you can use "static" instance to store it.
static String storage;
#Test
public void method1() {
storage = "Hello"
}
#Test
public void method2() {
Assert.assertThat(something, is(storage));
}
How much processing time do these tests take? If not a lot, then why sweat it. Sure you will create some object unnecessarily, but how much does this cost you?
#Test
void testCreateObject() {
Object obj = unit.createObject();
}
#Test
void testReadObject() {
Object obj = null;
try {
obj = unit.createObject(); // this duplicates tests aleady done
} catch (Exception cause) {
assumeNoException(cause);
}
unit.readObject(obj);
}
in this basic example, the variable is changed in the test A, and can be used in the test B
public class BasicTest extends ActivityInstrumentationTestCase2 {
public BasicTest() throws ClassNotFoundException {
super(TARGET_PACKAGE_ID, launcherActivityClass);
}
public static class MyClass {
public static String myvar = null;
public void set(String s) {
myvar = s;
}
public String get() {
return myvar;
}
}
private MyClass sharedVar;
#Override
protected void setUp() throws Exception {
sharedVar = new MyClass();
}
public void test_A() {
Log.d(S,"run A");
sharedVar.set("blah");
}
public void test_B() {
Log.d(S,"run B");
Log.i(S,"sharedVar is: " + sharedVar.get());
}
}
output result is:
run A
run B
sharedVar is: blah