SQLite database verification after nhibernate schema generation - unit-testing

What is the simplest most effective way to verify that your SQLite db is actually out there after using NHib's schema generation tool?
Cheers,
Berryl
EDIT
I am hoping there is something tied to the ISession (like the connection property) that can be tested; sometimes when running a series of tests it seems like a good session (IsOpen & IsConnected are true) but the db is not there (a query against it gets an error like 'no such table').
EDIT - WHAT I AM DOING NOW
Connection string & other cfg properties
public static Configuration GetSQLiteConfig()
{
return new Configuration()
.SetProperty(ENV.Dialect, typeof (SQLiteDialect).AssemblyQualifiedName)
.SetProperty(ENV.ConnectionDriver, typeof (SQLite20Driver).AssemblyQualifiedName)
.SetProperty(ENV.ConnectionString, "Data Source=:memory:;Version=3;New=True;Pooling=True;Max Pool Size=1")
.SetProperty(ENV.ProxyFactoryFactoryClass, typeof (ProxyFactoryFactory).AssemblyQualifiedName)
.SetProperty(ENV.ReleaseConnections, "on_close")
.SetProperty(ENV.CurrentSessionContextClass, typeof (ThreadStaticSessionContext).AssemblyQualifiedName);
}
How I test the db now, for lack of something 'better' (this tests the mappings)
public static void VerifyAllMappings(ISessionFactory sessionFactory, ISession session)
{
Check.RequireNotNull<ISessionFactory>(sessionFactory);
Check.Require(session.IsOpen && session.IsConnected);
_verifyMappings(sessionFactory, session);
}
private static void _verifyMappings(ISessionFactory sessionFactory, ISession session) {
try {
foreach (var entry in sessionFactory.GetAllClassMetadata())
{
session.CreateCriteria(entry.Value.GetMappedClass(EntityMode.Poco))
.SetMaxResults(0).List();
}
}
catch (Exception ex) {
Console.WriteLine(ex);
throw;
}
}
public static void VerifyAllMappings(ISessionFactory sessionFactory, ISession session)
{
Check.Require(!sessionFactory.IsClosed);
Check.Require(session.IsOpen && session.IsConnected);
try {
foreach (var entry in sessionFactory.GetAllClassMetadata())
{
session.CreateCriteria(entry.Value.GetMappedClass(EntityMode.Poco))
.SetMaxResults(0).List();
}
}
catch (Exception ex) {
Debug.WriteLine(ex);
throw;
}
}
I generate the schema in a session provider whenever a new session is opened:
public ISession Session
{
get
{
var session = (ISession)CallContext.GetData(_lookupSessionKey);
try
{
if (session == null)
{
_log.Debug("Opening new Session for this context.");
session = FactoryContext.Factory.OpenSession();
if(RunTypeBehaviorQualifier != RunType.Production)
SchemaManager.GenerateNewDb(FactoryContext.Cfg, session.Connection);
CallContext.SetData(_lookupSessionKey, session);
}
}
catch (HibernateException ex)
{
throw new InfrastructureException(ex);
}
return session;
}
}
Now this is all probably way over engineered, but I need multiple database connections and I've been having trouble keeping it simpler & working. It's also a lot of info for one question, but maybe someone else has actually got this all down to a science. The test below runs fine within it's own test fixture, but not in conjunction with other tests.
[Test]
public void Schema_CanGenerateNewDbWithSchemaApplied()
{
DbMappingTestHelpers.VerifyAllMappings(_dbContext.FactoryContext.Factory, _dbContext.Session);
}

Berryl,
As far as I can see you're strugling against mapped entities because you are using different connections. Is there any requirement that obligates you to use more than one "real" DB connection? I mean, can your tests share the same session (logically)? If not, you can simply configure your DB as:
<property name="connection.connection_string">Data Source=NonTransactionalDB.txt;Version=3;New=True;Pooling=True;Max Pool Size=1;</property>
The important part of it are the pooling options. As every session will aways use the same connection, you won't have problems with recreating the schema everytime.
It's important to remeber, though, that it introduces to you some limitations about transactions. As SQLite can't handle more than one transaction per connection, running your tests in parallel can bring you problems (something like a "database file is locked" Exception").
Cheers,
Filipe

Berryl, just to make it easir to visualize, I'll post as another answer. Feel free to give me another up if it helps you. :)
Below is the code that I use to check if my NH configuration object was properly configured.
// assert: verify some properties just to see if connection properties were applyed ane entities mapped
Assert.AreEqual<string>(cfg.Properties["connection.connection_string"], #"Server=localhost;Initial Catalog=MoveFrameworkDataNHibernate;User Id=sa;Password=sa");
Assert.AreEqual<string>(cfg.Properties["dialect"], "NHibernate.Dialect.MsSql2000Dialect");
Assert.IsNotNull(cfg.GetClassMapping(typeof(MappedEntity)));
Sincerely, I don't fell safe too that the DB is available checking the configuration object, but that's a way to know: yeah, my entities are there and I'm pointing to the right DB.
I understand that you are afraid of using a second SQLite connection and the DB was exposed in a previous one, so you will get undesired exceptions, but as far as I can see, the only other option to check if your entities are there would be something like the code below. As it refers to the SessionFactory, though, it helps nothing more than the previous option.
tx.Session.SessionFactory.GetClassMetadata(typeof(MappedEntity)) != null
The last option that I can think, in this case, would be to execute a SQL directly to your DB with an EXISTS check. I don't know how agnostic the EXISTS command is between ALL DBs implementations, but to a simple check like we're talking here it shouldn't be a big problem.
Hope this helps!
BTW: it's jfneis. Neis is a surname. Nothing to do with fries, french fries or something like. :)
Cheers.
Filipe

Related

Service #Transactional exception translation

I have a web service with an operation that looks like
public Result checkout(String id) throws LockException;
implemented as:
#Transactional
public Result checkout(String id) throws LockException {
someDao.acquireLock(id); // ConstraintViolationException might be thrown on commit
Data data = otherDao.find(id);
return convert(data);
}
My problem is that locking can only fail on transaction commit which occurs outside of my service method so I have no opportunity to translate the ConstraintViolationException to my custom LockException.
Option 1
One option that's been suggested is to make the service delegate to another method that's #Transactional. E.g.
public Result checkout(String id) throws LockException {
try {
return someInternalService.checkout(id);
}
catch (ConstraintViolationException ex) {
throw new LockException();
}
}
...
public class SomeInternalService {
#Transactional
public Result checkout(String id) {
someDao.acquireLock(id);
Data data = otherDao.find(id);
return convert(data);
}
}
My issues with this are:
There is no reasonable name for the internal service that isn't already in use by the external service since they are essentially doing the same thing. This seems like an indicator of bad design.
If I want to reuse someInternalService.checkout in another place, the contract for that is wrong because whatever uses it can get a ConstraintViolationException.
Option 2
I thought of maybe using AOP to put advice around the service that translates the exception. This seems wrong to me though because checkout needs to declare that it throws LockException for clients to use it, but the actual service will never throw this and it will instead be thrown by the advice. There's nothing to prevent someone in the future from removing throws LockException from the interface because it appear to be incorrect.
Also, this way is harder to test. I can't write a JUnit test that verifies an exception is thrown without creating a spring context and using AOP during the tests.
Option 3
Use manual transaction management in checkout? I don't really like this because everything else in the application is using the declarative style.
Does anyone know the correct way to handle this situation?
There's no one correct way.
A couple more options for you:
Make the DAO transactional - that's not great, but can work
Create a wrapping service - called Facade - whose job it is to do exception handling/wrapping around the transactional services you've mentioned - this is a clear separation of concerns and can share method names with the real lower-level service

How to update test case results at bulk in Testlink

I've recently started using testlink test management tool in my project and I'm facing a new problem on bulk updation of test cases in testlink.
This is not a problem for manual test cases but for automation it is tedious to update the result (Pass or Fail) of every single test case that you executed.
I have around 5000+ test cases and 50% of them are automated so when the automated.
So, when the automation script is finished executing 2500+ test cases for a particular release, I need to update the result of all these test cases manuall in testlink as Pass or Fail.
I also tried to link the automation tool with testlink but that didn't worked out.
So, I just want to know if there's any easy way to bulk update the test cases in testlink. May be using some DB queries and all?
I think it's difficult because you should know several data in order to insert the correct information for your project, test plan, build, testsuite, testcase and testcase version. So, you will need all this information.
Anyway, the table to insert the information is "executions" with the following query you can check the needed information:
select * from executions;
Regards, David.
1) you can use the XML-RPC API
2) generate a XML file with Format for importing results, then upload it manually
avoid using direct access to DB via SQL
iam also updating the test link using Selenium webdriver
the code is below :-
public class appFunctions extends Keywords {
// Substitute your Dev Key Here
public static String DEV_KEY= "1eab09b6158d9df31e76142b85253243";
public static String SERVER_URL = "https://testlink.fondsdepotbank.de/testlink/lib/api/xmlrpc/v1/xmlrpc.php";
public static void clearXLResults() throws IOException
{
try
{
int testStepsRow=DriverScript.xlObj.getRowCount("TestSteps");
int controllerRow=DriverScript.xlObj.getRowCount("Controller");
//Clear previous results
for(int i=2;i<=testStepsRow;i++)
{
DriverScript.xlObj.setCellData("TestSteps",DriverScript.testStepsStatusCol, i, "");
}
for(int j=2;j<=controllerRow;j++)
{
DriverScript.xlObj.setCellData("Controller", DriverScript.controllerStatusCol, j, "");
}
}catch(Exception e)
{
e.printStackTrace();
log.writeLog("Unable to clear previous test results in excel");
}
}
public static void updateResultsTestLink() throws IOException
{
try
{
TestLinkAPIClient api=new TestLinkAPIClient(DEV_KEY, SERVER_URL);
String result;
//read controller status
int controllerRow=DriverScript.xlObj.getRowCount("Controller");
for(int k=2;k<=controllerRow;k++)
{
String currentRowStatus=DriverScript.xlObj.getCellData("Controller",DriverScript.controllerStatusCol,k);
String currentRowProject=DriverScript.xlObj.getCellData("Controller",DriverScript.controllerProjectCol,k);
String currentRowPlan=DriverScript.xlObj.getCellData("Controller",DriverScript.controllerPlanCol,k);
String currentRowBuild=DriverScript.xlObj.getCellData("Controller",DriverScript.controllerBuildCol,k);
String currentRowTCID=DriverScript.xlObj.getCellData("Controller",DriverScript.controllerTCIDCol,k);
if(currentRowStatus.equalsIgnoreCase("pass"))
{
result= TestLinkAPIResults.TEST_PASSED;
api.reportTestCaseResult(currentRowProject, currentRowPlan, currentRowTCID, currentRowBuild, null, result);
}
if(currentRowStatus.equalsIgnoreCase("fail"))
{
result= TestLinkAPIResults.TEST_FAILED;
api.reportTestCaseResult(currentRowProject, currentRowPlan, currentRowTCID, currentRowBuild, null, result);
}
}
}catch(Exception e)
{
e.printStackTrace();
log.writeLog("Unable to update results in Testlink");
}
}

unit test all permutations or start publicly exposing more? Where's the line?

I know that there have been a few posts about this already but I wanted to post one with a concrete example to focus on the gray areas you face when choosing between testing private/internal methods and refactoring into a public class.
Say I have a simple class I want to test that has some internal code refactored into a private or internal method.
Example:
public class Guy
{
public void DoSomeWork()
{
try
{
//do some work
}
catch(Exception e)
{
LogError(e.Message);
}
try
{
//do some more work
}
catch(SomeSpecificException e)
{
LogError(e.Message);
}
}
private void LogError(string message)
{
//if logging folder doesn't exist, create it
//create a log file
//log the message
}
}
Most people would advise that I should take the error logging logic out and put it in a class marked public because it's starting to be complex enough to stand on its own, but the assembly's internal error logging logic shouldn't be exposed publicly--it's not a logging assembly.
If I don't do that, then every time I have code that could call LogError(), I need to have subsequent tests that retest all of the internal logic for LogError(). That quickly becomes oppressive.
I also understand I can mark the method as internal and make it visible to a testing assembly but it's not very "pure."
What sort of guidelines can I abide by in this type of situation?
but the assembly's internal error logging logic shouldn't be exposed publicly
That's true. It can be internal and tested as such. But this
private void LogError(string message)
{
//if logging folder doesn't exist, create it
//create a log file
//log the message
}
Calls for a separate component. Create folder? Create file? Whatever DoSomeWork does, it should have nothing to do with creating log file internals. All it should require is simple "log this message"-feature. Files, folders, formats -- it's all specific to logging component and shouldn't leak to any other.
Your sample code is perfect example of single responsibility principle violation. Extracting logging to fix it solves your testing issues completely.
One possible way to handle this is instead of logging the error in your DoSomeWork method, you simply raise the error, and let it get handled upstream. Then you test that the error was raised, and for the purposes of testing the DoSomeWork method, you don't care what happens after that.
Whether or not this is a good idea depends a lot on how the rest of your program is structured, but having LogError sprinkled all over the place may indicate you need a broader error handling strategy that this approach requires.
UPDATE:
public void DoSomeWork() {
try {
WorkPartA()
}
catch(Exception e) {
LogError(e.Message)
}
try {
WorkPartB()
}
catch(SomeSpecificException e) {
LogError(e.Message)
}
}
public void WorkPartA() {
//do some work
}
public void WorkPartB() {
//do some more work
}
As a response to your comment below, the problem might be that you need to break up your code into smaller pieces. This approach allows you to test raising the exception within WorkPartA() and WorkPartB() individually, while still allowing the process to run if WorkPartA fails. As far as testing DoSomeWork() in this case, I might not even bother. There's a high probability it would be a very low-value test anyway.

How can I unit test a method with database access?

I have already had some difficulties on unit tests and I am trying to learn it while using a small project I currently am working on and I ran into this problem these two problems that I hope you can help me with
1- My project is an MVC project. At which level should my unit tests start? They should focus only on the business layer? Should they also test actions on my controllers?
2- I have a method that verifies an username format and then access the DB to check if it is available for use. The return is a boolean whether this username is available or not.
Would one create a unit test for such a method?
I would be interested on testing the format verification, but how would I check them without querying the DB? Also, if the formats are correct, but the username is already in use, I will get a false value, but the validation worked. I could decouple this method, but the DB verification should only happen if the format is correct, so they should somehow be tied.
How would someone with unit tests knowledge solve this issue. Or how would someone refactor this method to be able to test it?
I could create a stub for the DB access, but how would I attach it to my project on the user testing but detach it when running locally?
Thanks!
In your specific case, one easy thing you could do is decompose your verification method into 3 different methods: one to check formatting, one to check DB availability, and one to tie them both together. This would allow you to test each of the sub-functions in isolation.
In more complex scenarios, other techniques may be useful. In essence, this is where dependency injection and inversion of control come in handy (unfortunately, those phrases mean different things to different people, but getting the basic ideas is usually a good start).
Your goal should be to decouple the concept of "Check if this username is available" from the implementation of checking the DB for it.
So, instead of this:
public class Validation
{
public bool CheckUsername(string username)
{
bool isFormatValid = IsFormatValid(username);
return isFormatValid && DB.CheckUsernameAvailability(username);
}
}
You could do something like this:
public class Validation
{
public bool CheckUsername(string username,
IUsernameAvailabilityChecker checker)
{
bool isFormatValid = IsFormatValid(username);
return isFormatValid && checker.CheckUsernameAvailability(username);
}
}
And then, from your unit test code, you can create a custom IUsernameAvailabilityChecker which does whatever you want for testing purposes. On the other hand, the actual production code can use a different implementation of IUsernameAvailabilityChecker to actually query the database.
Keep in mind that there are many, many techniques to solve this kind of testing problem, and the examples I gave are simple and contrived.
Testing against outside services can be done using mocking. If you've done a good job using interfaces it's very easy to mock various parts of your application. These mocks can be injected into your unit and used like it would normally handle it.
You should start unit testing as soon as possible. If your application is not complete or code needed for testing is absent you can still test against some interface you can mock.
On a sidenote: Unit testing is about testing behavior and is not an effective way to find bugs. You will find bugs with testing but it should not be your goal.
For instance:
interface UserService {
public void setUserRepository(UserRepository userRepository);
public boolean isUsernameAvailable(String username);
}
class MyUserService implements UserService {
private UserRepository userRepository;
public vois setUserRepository(UserRepository userRepository) {
this.userRepository = userRepository;
}
public boolean isUsernameAvailable(String username) {
return userRepository.checkUsernameAvailability(username);
}
}
interface UserRepository {
public boolean checkUsernameAvailability(String username);
}
// The mock used for testing
class MockUserRepository {
public boolean checkUsernameAvailability(String username) {
if ("john".equals(username)) {
return false;
}
return true;
}
}
class MyUnitTest {
public void testIfUserNotAvailable() {
UserService service = new UserService();
service.setUserRepository(new MockUserRepository);
assertFalse(service.isUsernameAvailable('john')); // yep, it's in use
}
public void testIfUserAvailable() {
UserService service = new UserService();
service.setUserRepository(new MockUserRepository);
assertTrue(service.isUsernameAvailable('mary')); // yep, is available
}
}

Where should I place this code in MVC?

My code works perfectly, BUT. Whats the best practice in this case?
Here is the code that is important.
This is in the controller.
private IProductRepository repository;
[HttpPost]
public ActionResult Delete(int productId) {
Product prod = repository.Products.FirstOrDefault(p => p.ProductID == productId);
if (prod != null) {
repository.DeleteProduct(prod);
TempData["message"] = string.Format("{0} was deleted", prod.Name);
}
return RedirectToAction("Index");
}
This is the repository (both Interface etc)
public interface IProductRepository {
IQueryable<Product> Products { get; }
void SaveProduct(Product product);
void DeleteProduct(Product product);
}
And here comes the repository..... (the part that is important) I want to point out though... that this is not a fakeclass as is pretty clear. The testing is done on fakeclasses.
private EFDbContext context = new EFDbContext();
public IQueryable<Product> Products {
get { return context.Products; }
}
public void DeleteProduct(Product product) {
context.Products.Remove(product);
context.SaveChanges();
}
Well first question:
When doing testing on this, I will make a two TestMethods on the Controller in "ControllerTest". "Can_delete_valid_product" and "Cannot_delete_invalid_product". Is there any point in having a testclass for the repository? Like "RepositoryTest", afterall the controller tests if the deletefunction works no need to test it twice right?
Second question:
In this I test in the controller if the product exists, before trying to delete it. If it exists I call the deletefunction in the repository. This means that there should never be the posibility of an exception. BUT you could still create an exception in the repository if you send down null. (which cant happen here but you could still do it if you forget to check if null). Question is if the testing if product exists should be done in the repository instead?
I prefer to keep logic out of the controller for the most part. A test of the controller action verifies if the repository is called, but the repository itself is mocked in that test. I would make the repository responsible for handling null checking.
Personally I create separate tests for my repositories/data access to ensure that it works properly. The controllers themselves would be tested with mocks.
Actually it's entirely possible (just maybe not that likely) that someone could delete a product just as someone else is trying to delete it. In this case you probably don't care/need to know that someone did though so I would probably just swallow that exception in the repository (though I would log it first). In terms of null checking/defensive programming that's entirely a personal choice. Some people leave checks like that to the entry points of the system where as others will build a layered defense that has additional checks throughout the code. The problem is that these checks can get quite ugly which is a big part of why I wish Code Contracts would gain more traction.
This means that there should never be the posibility of an exception. BUT you could still create an exception in the repository if you send down null. (which cant happen here but you could still do it if you forget to check if null).
Or if it's deleted after you check it exists but before you delete it. Or if you lose connection to the repository (or will the method never return in this case?). You can't avoid exceptions in this way.