Why does my JUnit test (that modifies a database entry) fail - java

EDIT: replaced 'retrieve.name == "name1"' by 'retrieve.name.equals("name1")'.
EDIT2: Added #BeforeClass and #AfterClass (credit: http://digitalsanctum.com/2012/06/01/play-framework-2-tutorial-ebean-orm/).
I'm writing JUnit tests for a play web app and for some odd reason I can't seem to modify the database entries. Here's the simplest example I could come up with that illustrates the problem:
#BeforeClass
public static void setup() throws IOException {
app = Helpers.fakeApplication(Helpers.inMemoryDatabase());
Helpers.start(app);
server = Ebean.getServer("default");
ServerConfig config = new ServerConfig();
config.setDebugSql(true);
ddl = new DdlGenerator((SpiEbeanServer) server, new H2Platform(), config);
// drop
String dropScript = ddl.generateDropDdl();
ddl.runScript(false, dropScript);
// create
String createScript = ddl.generateCreateDdl();
ddl.runScript(false, createScript);
}
#AfterClass
public static void stopApp() {
// drop
String dropScript = ddl.generateDropDdl();
ddl.runScript(false, dropScript);
Helpers.stop(app);
}
#Test
public void UserModify(){
// create user (User extends Model)
User user = new User();
user.id = (long) 1;
user.name = "name1";
user.save();
// modify
user.name = "name2";
user.update();
user.save();
// look-up
User retrieve = User.find.byId((long) 1);
assertFalse("Old name", retrieve.name.equals("name1"));
}
Needless to say this should pass, but it doesn't... I know you can use "update()" to change database fields, because someone else on the project says he uses it like that and it works.
Play Framework documentation: http://www.playframework.com/documentation/2.1.1/Home
Any ideas why this test fails?

This is happening because of a problem in Play Framework.
Play doesn't enhance code in "test" folder, only in "app" folder.
Because of that getters and setters are not generated, and Ebean is relying on setters to detect that object is dirty and to support lazy loading. This way in your case Ebean doesn't know that property was updated on object.
As a simple solution, you can create getters and setters yourself. Also, that seems to be fixed already and probably should be included in next Play release: https://github.com/playframework/Play20/blob/master/framework/test/integrationtest-java/test/models/EbeanEnhancementTest.java
Here's a simple Play project with User model and working test: https://github.com/pharod/so-play2-issue1
See more details on getters and setters generation by Play here, in "Caveats" section near bottom of page: http://www.playframework.com/documentation/2.1.1/JavaEbean

As others have stated, you should use .equals() for string equality.
But the main problem is that to run this kind of tests (accessing the database) You need a running application.
In play, this could be done, by running a fake application with the test. Check out this guide:
http://www.playframework.com/documentation/2.0/JavaTest

Related

How to capture saved value in Java?

I am trying to create a unit test for the following method:
public CommandDTO update(final MenuRequest request) {
Menu menu = menuRepository.findByUuid(request.getUuid());
MenuConverter.convert(request, menu); // map fields
Menu saved = menuRepository.save(menu);
return CommandDTO.builder().uuid(saved.getUuid()).build();
}
I want to capture saved parameter as it is not returned from the method using the following unit test:
#RunWith(MockitoJUnitRunner.class)
public class MenuServiceImplTest {
#InjectMocks
private MenuServiceImpl menuService;
#Captor
private ArgumentCaptor<Menu> menuCaptor;
// mocks (code omitted for brevity)
#Test
public void test_Update() {
// ...
CommandDTO result = menuService.update(request);
verify(menuRepository).save(menuCaptor.capture());
final Menu captured = menuCaptor.getValue();
}
}
However, the parameter in menuRepository.save() is the unsaved parameter, but I need to capture saved parameter. So, how can I do this? Should I use #Spy instead of ArgumentCaptor?
If that is a unit test, then I assume you already mock MenuRepository.
To properly mock MenuRepository, you need to define the behavior of menuRepository.findByUuid(request.getUuid()) and menuRepository.save(menu).
Once you define menuRepository.findByUuid(request.getUuid()), you need to create a Menu instance. All you need to do is, to check if the fields of that menu are updated properly.
Let's try to break down the functionality of the MenuServiceImpl's update method:
public CommandDTO update(final MenuRequest request) {
Menu menu = menuRepository.findByUuid(request.getUuid());
MenuConverter.convert(request, menu); // map fields
Menu saved = menuRepository.save(menu);
return CommandDTO.builder()
.uuid(saved.getUuid())
.build();
}
Here is what this method is doing:
Fetching existing Menu from the repository, finding by uuid
Converting it i.e. updating it from request
Persisting it back in repository using save
Creating a CommandDTO from saved uuid.
Now, when we write UnitTest for a unit then that means we are testing the working of that unit only.
Here MenuServiceImpl is not responsible to ensure whether the values were mapped correctly or if the updated value was saved correctly, the only work MenuServiceImpl performs is to call these dependencies in a particular order and that is all we need to test here.
So, here is a correct test for MenuServiceImpl's update method:
#Test
void test_Update() {
MenuRequest request = new MenuRequest("1234");
Menu existingMockMenu = mock(Menu.class);
when(menuRepository.findByUuid("1234")).thenReturn(existingMockMenu);
Menu savedMockMenu = mock(Menu.class);
when(menuRepository.save(existingMockMenu)).thenReturn(savedMockMenu);
menuServiceImpl.update(request);
verify(menuRepository).save(existingMockMenu);
}
If at all you want to test if MenuRepository is saving the Menu correctly, you will have to write a new test for MenuRepository, if this is actually a repository that interacts with the database, then it will be helpful to write DB Integration Test.
Regarding using ArgumentCaptor, let's suppose your MenuConverter is changing the values of the menu, something like this:
public class MenuConverter {
public static void convert(MenuRequest request, Menu menu) {
menu.setName(request.getName() + "_new");
}
}
then first of all, you should have a different test for MenuConverter that tests this logic, still if you want to test this in the test of MenuServiceImpl itself, then you don't have to use ArgumentCaptor, you can use something like:
#Test
void test_Update() {
// same as above
verify(existingMockMenu).setName("Menu1_new");
}
This verifies that MenuConverter attempted to update the name of your existingMockMenu

Is there a way to drop all tables or truncate inside a postgres testcontainer

I'm looking for a way to keep my component tests self contained.
So to achieve this behavior, in some of the tests I need to have a 'clean database' or at least a 'clean table'. I still couldn't find a way to do this inside a testcontainer.
So here is what I've tried so far:
My container setup class:
public class PostgreSqlTestContainer implements QuarkusTestResourceLifecycleManager {
public static final PostgreSQLContainer<?> POSTGRES = new PostgreSQLContainer<>("postgres:alpine");
#Override
public Map<String, String> start() {
POSTGRES.start();
return some_db_config_as_per_doc;
}
#Override
public void stop() {
POSTGRES.stop();
}
Here is the tests class:
#QuarkusTest
#QuarkusTestResource(PostgreSqlTestContainer.class)
class UserResourcesTest {
#Test
scenario_one(){
// create a new user
// do some stuff (#POST.. check HTTP == 201)
}
#Test
scenario_two(){
// create new user
// do some stuff (#POST.. check HTTP == 201) (pass)
// look for all users on database
// do more stuff (#GET.. check HTTP == 200) (pass)
// assert that only 1 user was found
// since scenario_one should not interfere with scenario_two (fail)
}
}
The second scenario fails since some 'dirty' from the first test was still on the db container.
I've tried to stop/start the container for each test. (very, very slow process, and sometimes I get an error, and very slow again).
#BeforeEach
void setup(){
PostgreSqlTestContainer.POSTGRES.stop();
PostgreSqlTestContainer.POSTGRES.start();
}
Also tried to truncate the table / drop the whole db:
#Inject
EntityManager entityManager;
#BeforeEach
private void rollBack(){
truncate();
}
void truncate(){
Query nativeQuery = entityManager.createNativeQuery("DROP DATABASE IF EXISTS db_name");
nativeQuery.executeUpdate();
}
I'm looking for any workaround for this problem, I just want to somehow use a #BeforeEach to clean up the DB before each test. I mean, all I want is a clean environment for each test.
Create a template test database with the name test_template.
After each test,
disconnect all sessions from the test database (not required with PostgreSQL v13):
SELECT pg_terminate_backend(pid)
FROM pg_stat_activity
WHERE datname = 'test';
drop the database with
DROP DATABASE test;
In v13, use the additional FORCE option.
create a new test database with
CREATE DATABASE test TEMPLATE test_template;
Note: you have to enable autocommit in the JDBC driver for CREATE DATABASE and DROP DATABASE to work.

Why and How to mock Model-Helperclasses?

I am reading a lot about unit testing, mocking, and all that stuff. I am currently also reading the book "Growing Object-Oriented Software Guided by Tests" by Steve Freeman and Nat Pryce.
I am starting to understand a lot of stuff but missing one crucial point, where I tried to find the answer anywhere online but am not satisfied yet.
In the following example I have an Online Shop, which receives messages from a third-party library, translates those, interpret them and eventually persist them into the database if needed. In a concrete case, I receive a message about a change of the address of a credit card of a user and want to store that information into a database.
The structure looks like this:
src/
domain/
MessageTranslator.java
ShopEventListener.java
ShopHandler.java
model/
CreditCard.java
CreditCardBase.java
CreditCardBuilder.java
User.java
UserBase.java
UserBuilder.java
test/
MessageTranslatorTest.java
ShopHandlerTest.java
MessageTranslatorTest
public class MessageTranslatorTest {
#Test
public void notifiesCCAddressChangedWhenChangeCCAddressMessageReceived() throws Exception {
ShopEventListener listenerMock = mock(ShopEventListener.class);
MessageTranslator messageTranslator = new MessageTranslator(listenerMock);
messageTranslator.processMessage("action=changeCCAddress; firstname=John; lastname=Doe; address=foobar3");
verify(listenerMock).ccAddressChanged("John", "Doe", "foobar3");
}
}
MessageTranslator (very simple for now)
public class MessageTranslator {
private final ShopEventListener listener;
public MessageTranslator(ShopEventListener userEventListener) {
listener = userEventListener;
}
public void processMessage(String message) throws Exception {
String[] attributes = message.split(";");
listener.ccAddressChanged(attributes[1].split("=")[1].trim(), attributes[2].split("=")[1].trim(), attributes[3].split("=")[1].trim());
}
}
ShopHandler
public class ShopHandler implements ShopEventListener {
#Override
public void ccAddressChanged(String firstname, String lastname, String newAddress) throws Exception {
// find a user (especially userid) in the Database for given firstname and lastname
UserBase userBase = new UserBase();
User user = userBase.find(aUser().withFirstname(firstname).withLastname(lastname).build());
if (user == null) {
throw new Exception();
}
// find the matching CreditCard for the userid in the database
Integer userid = user.getUserid();
CreditCardBase ccBase = new CreditCardBase();
CreditCard cc = ccBase.find(aCreditCard().withUserid(userid).build());
if (cc == null) {
throw new Exception();
}
// change address locally and then write it back to the database
cc.setAddress(newAddress);
cc.persist();
}
}
ShopHandlerTest
public class ShopHandlerTest {
#Test
public void changesCCAddressWhenChangeCCAddressEventReceived() throws Exception {
ShopHandler shop = new ShopHandler();
shop.ccAddressChanged("John", "Doe", "foobar3");
// TODO: How to test the changes in inner object?
}
}
This is where I always stumble.
Do I want to mock the helper classes UserBase and CreditCardBase to not perform any database queries but just return a prepared fake object?
Do I want to mock the persist-method to not write any real data to the database but maybe just test the parameters of the object to be persisted and have other (integration) tests test the database operations?
If 1. and 2. will be answered with yes, then what am I actually testing here? Is it worth unittesting this unit then?
Does the structure make sense this way?
If 1. and 2. will be answered with yes, then how do I mock the inner objects? I feel like dependency injection is the wront approach here, because first its no real dependency, but some helper classes, second (and more important imo) the ShopHandler class could be flooded with dependencies, as it might need alot of different helper classes and model classes to perform all the different actions. What if I just want to update the birthdate of a user based on an external message, do I still have to path all the dependencies like CreditCardBase and stuff?
Sorry for the long post, but it would be really awesome if you could push me in the right direction.
If you need more code for the above to understand, let me know.
Do I want to mock the helper classes UserBase and CreditCardBase to not perform any database queries but just return a prepared fake object?
Looks like your "helper classes" are actually repositories/DAOs. You normally want to test your business logic separately from DAOs, without the real database access. So yes, you should probably mock these DAOs and prepare the calls to them as they would work in reality. Prepared fake object is OK in most cases. You may also want to verify that your mocked DAO was actually called.
Do I want to mock the persist-method to not write any real data to the database but maybe just test the parameters of the object to be persisted and have other (integration) tests test the database operations?
I find it a bit strange that you seem to have the persist method in your business entity. Normally DAOs implement this type of methods.
Yes, if you test business logic you should mock the persist call to DAOs as well. If you don't do this, you'll be making tests of the business logic much heavier that they should be.
Yes, you should test your DAOs as well but separately from the business logic.
If 1. and 2. will be answered with yes, then what am I actually testing here? Is it worth unittesting this unit then?
You're testing you business logic. Just what is implemented in your ccAddressChanged method. Roughly:
if the user could not be found, an exception is thrown.
if user is found but users credit card could not be found, an exception is thrown.
if both could be found then credit card is persisted with an updated address.
Does the structure make sense this way?
It is not quite what I'm used to. You seem to have data access logic in entities, then you also have this "base" helper classess...
If 1. and 2. will be answered with yes, then how do I mock the inner objects?
With "inner objects" you probaby mean these helper classes. They are actually more that "helper classes", they are DAOs providing access to the database. You can pass or inject them from the outside. Basically this is dependency injection, your business logic depends on these DAO components. If you are able to pass them from the outside then in your test you can mock DAOs and pass mocks to your business service. With DI frameworks like Spring you'll have framework support for this.
Here'a a rough sketch of how a test for your ShopHandler class could look like with Spring and Mockito:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(classes = {ShopHandler.class})
public class ShopHandlerTest {
#Autowired
private ShopHandler sut;
#MockBean
private UserRepository userRepository;
#MockBean
private CreditCardRepository creditCardRepository;
#Test(expected = UserNotFoundException.class)
public void throwsUserNotFoundExceptionIfUserIsUnknown() {
when(userRepository.findUserByFirstNameAndLastName("Scott", "Tiger").thenReturn(null);
sut.ccAddressChanged("Scott", "Tiger", "Some Address");
}
#Test
public void successFullyUpdatesCreditCardAddress() {
when(userRepository.findUserByFirstNameAndLastName("Scott", "Tiger").thenReturn(new User("userId", ...));
when(creditCardRepository.findByUserId("userId")).thenReturn(new CreditCard(...));
ArgumentCaptor<CreditCard> creditCardCaptor = ArgumentCaptor.forClass(CreditCard.class);
verify(creditCardRepository).save(creditCardCaptor.capture());
sut.ccAddressChanged("Scott", "Tiger", "Some Address");
asserthThat(creditCardCaptor.getValue().getAddress()).isEqualTo("Some Address");
}
}
I feel like dependency injection is the wront approach here,
Dependency injection is a very sensible approach here.
because first its no real dependency,
Well, of course these are real dependencies.
but some helper classes,
Where do you think it end being a "helper class" and starts being a "real dependency"? What you call "helper classes" pretty much resemble DAOs which absolutely are "real dependencies".
second (and more important imo) the ShopHandler class could be flooded with dependencies, as it might need alot of different helper classes and model classes to perform all the different actions.
If you need to perform all these actions and need all these dependencies to do this, then this is the reality. The question is, however - do you really have to implement all of these actions in just one business service? Can't you divide this into many business services? You'll get smaller more focused classes then, and they will only need a few dependencies.
Since you're creating UserBase and CreditCard instances using new keyword in the method ccAddressChanged() - you cannot mock them!
In order to be able to mock them use DI - Dependency Injection (also called IoC - Inversion Of Control) by injecting instances of these class to ccAddressChanged():
change the signature of the class from:
public void ccAddressChanged(String firstname, String lastname, String newAddress)
to:
public void ccAddressChanged(String firstname, String lastname, String newAddress, UserBase userBase, CreditCard creditCard)
This way, you'll be able to mock them (using Mockito or any other mocking framework) and sending the mocks to the method.
Example of how the test will look, using Mockito:
#Test
public void changesCCAddressWhenChangeCCAddressEventReceived() throws Exception {
ShopHandler shop = new ShopHandler();
// mock UserBase and its behavior
UserBase mockedUserBase = mock(UserBase.class)
when(mockedUserBase.find(any()).thenReturns(mock(User.class));
// mock CreditCard
CreditCard mockedCreditCard = mock(CreditCard.class);
shop.ccAddressChanged("John", "Doe", "foobar3");
}
I feel like dependency injection is the wrong approach here, because
first its no real dependency, but some helper classes, second (and
more important imo) the ShopHandler class could be flooded with
dependencies
DI is not wrong:
It seems that ShopHandler class does have a real dependency on UserBase and CreditCardBase
To avoid "flooded" scenario you can inject them into the constructor of ShopHandler and save them into private fields. This way it's done only once during initialization and does not burden the user as well as doesn't expose implementation details.
Further, assuming that you refactored your code and now you're assigning UserBase and CreditCardBase in the constructor. I would refactor the code from:
#Override
public void ccAddressChanged(String firstname, String lastname, String newAddress) throws Exception {
// find a user (especially userid) in the Database for given firstname and lastname
UserBase userBase = new UserBase();
User user = userBase.find(aUser().withFirstname(firstname).withLastname(lastname).build());
if (user == null) {
throw new Exception();
}
// find the matching CreditCard for the userid in the database
Integer userid = user.getUserid();
CreditCardBase ccBase = new CreditCardBase();
CreditCard cc = ccBase.find(aCreditCard().withUserid(userid).build());
if (cc == null) {
throw new Exception();
}
// change address locally and then write it back to the database
cc.setAddress(newAddress);
cc.persist();
}
to:
#Override
public void ccAddressChanged(String firstname, String lastname, String newAddress) throws Exception {
User user = getUserByName(firstname, lastname);
CreditCard creditCard = getCCByUser(user);
setAddress(creditCard, newAddress);
}
and now you don't have to unit-test this ccAddressChanged() anymore. What you should do is test, and each one of the three methods: getUserByName, getCCByUser and setAddress. And each one of them is easy to mock and test!
Here is how I would write integration tests for ShopHandler (as shown in the question, with no changes):
public class ShopHandlerTest {
#Tested(fullyUnitialized = true) AppDB appDB;
#Tested ShopHandler sut;
#Test(expected = UserNotFoundException.class)
public void throwsUserNotFoundExceptionIfUserIsUnknown() {
sut.ccAddressChanged("Unknown", "user", "...");
}
#Test
public void successFullyUpdatesCreditCardAddress() {
User user = new User("Scott", "Tiger");
appDB.persist(user);
CreditCard cc = new CreditCard(user, ...);
appDB.persist(cc);
String newAddress = "New address";
sut.ccAddressChanged(user.getFirstName(), user.getLastName(), newAddress);
appDB.refresh(cc);
assertEquals(newAddress, cc.getAddress());
}
}
Above, #Tested is a JMockit annotation with full DI support, and also JPA/EJB/etc. support. It can be used as a meta-annotation, so you could create a #SUT or #TestUtil annotation to simplify its use in tests.
The fully-reusable test utility class AppDB would be something like this:
public final class AppDB {
#PersistenceContext private EntityManager em;
#PostConstruct
private void startTransaction() { ... using em... }
#PreDestroy
private void endTransaction() { ... rollback using em... }
public void persist(Object entity) { em.persist(entity); }
public void refresh(Object entity) { em.refresh(entity); }
}
Notice how nice and simple those integration tests look. They basically only contain high-level code, essentially the same kind of code you would see in the production (SUT) code. No complicated mocking APIs to get you in trouble. They are also fast and stable.

Intercepting object returned by private method in a public method

I need to unit test a method, and I would like mock the behavior so that I can test the necessary part of the code in the method.
For this I would like access the object returned by a private method inside the method I am trying to test. I created a sample code to give a basic idea of what I am trying to achieve.
Main.class
Class Main {
public String getUserName(String userId) {
User user = null;
user = getUser(userId);
if(user.getName().equals("Stack")) {
throw new CustomException("StackOverflow");
}
return user.getName();
}
private User getUser(String userId) {
// find the user details in database
String name = ""; // Get from db
String address = ""; // Get from db
return new User(name, address);
}
}
Test Class
#Test (expected = CustomException.class)
public void getUserName_UserId_ThrowsException() {
Main main = new Main();
// I need to access the user object returned by getUser(userId)
// and spy it, so that when user.getName() is called it returns Stack
main.getUserName("124");
}
There are only two ways to access private:
using reflection
extend the scope
maybe waiting for Java 9 to use new scope mechanisms?
I would change the scope modifier from private to package scope. Using reflection is not stable for refactoring. It doesn't matter if you use helpers like PowerMock. They only reduce the boiler-plate code around reflection.
But the most important point is you should NOT test too deep in whitbox tests. This can make the test setup explode. Try to slice your code into smaller pieces.
The only information the method "getUserName" needs from the User-object is the name. It will validate the name and either throw an exception or return it. So it should not be necessary to introduce a User-object in the test.
So my suggestion is you should extract the code retreiving the name from the User-object into a separate method and make this method package scope. Now there is no need to mock a User-Object just the Main-Object. But the method has its minimal information available to work properly.
class Main {
public String getUserName(String userId) {
String username = getUserNameFromInternal(userId);
if (userName.equals("Stack")) {
throw new CustomException("StackOverflow");
}
return user.getName();
}
String getUserNameFromInternal(String userId) {
User user = getUser(userId);
return user.getName();
}
...
}
The test:
#Test (expected = CustomException.class)
public void getUserName_UserId_ThrowsException() {
Main main = Mockito.mock(new Main());
Mockito.when(main.getUserNameInternal("124")).thenReturn("Stack");
main.getUserName("124");
}
Your problem that call to new within your private method.
And the answer is not to turn to PowerMock; or to change the visibility of that method.
The reasonable answer is to "extract" that dependency on "something that gives me a User object" into its own class; and provide an instance of that class to your "Main" class. Because then you are able to simply mock that "factory" object; and have it do whatever you want it to do.
Meaning: your current code is simply hard-to-test. Instead of working around the problems that are caused by this, you invest time in learning how to write easy-to-test code; for example by watching these videos as a starting point.
Given your latest comment: when you are dealing with legacy code, then you are really looking towards using PowerMockito. The key part to understand: you don't "mock" that private method; you rather look into mocking the call to new User() instead; as outlined here.
You can use a PowerMock's mockPrivate but I don't recommend it.
If you has such a problem it usually mean that your design is bad.
Why not making the method protected?

How to test deletion in JUnit (Play Framework)?

I need to make a JUnit test that checks whether it is possible to delete something from the database. I'm using the Play 2.1 Framework with an in-memory database.
I tried assertNull(...), but that failed. I then tried assertNotNUll(...) and the test passes, but I'm not sure this is the best way to do it or that it can even confirm deletion. Is there a better way to check if an item has been deleted? Should I look up the object and expect an error?
Here's my code (I also have some #BeforeClass and #AfterClass code, but it's no relevant to my question):
#Test
public void UserDelete(){
// Test ID: 3
// creating a new user
User user = new User();
user.id = (long) 4;
user.facebookId = "0000004";
user.email = "test4#gmail.com";
user.name = "name4";
user.save();
// deleting the user
user.delete();
// checking deletion
assertNotNull(user);
}
In general you usually have to do something like this. Of course this is a crude example but it points out that you should use some persistence solution like JPA to persist your domain objects.
#Test(expected = WhateverObjectNotFoundException.class)
public void removeUserTest(){
User u = UserFactory.createTestUser();
Long id = myEntityManager.persist(u);
assertNotNull(id);
myEntityManager.remove(u);
myEntityManager.findById(id);
}
In my opinion the User shouldn't be responsible for its lifecycle since it does not make sense to ask an object to delete itself hence your question is somewhat paradox.
This solution later can be generalized so you won't have to write it all over again when you test for the same kind of behavior.
You should insert new object in DB, check that is was inserted, delete it and check that it was deleted. Most obvious way is to use select count(*) to get number of rows.
public class ApplicationTest extends WithApplication {
#Before
public void setup() {
start(fakeApplication(inMemoryDatabase("default-test"), fakeGlobal()));
}
#Test
public void UserModify() {
// create user (User extends Model)
User user = new User();
user.setId(1);
user.setName("name1");
user.save();
int rowCount = Ebean.find(User.class).where().eq("id", 1).findRowCount();
assertEquals(1, rowCount);
user.delete();
rowCount = Ebean.find(User.class).where().eq("id", 1).findRowCount();
assertEquals(0, rowCount);
}
}

Categories