I am pretty new to using Scala/Scalatest and I am trying to write a few test cases that mock a db.
I have a function called FindInDB(entry : String) that checks if "entry" is in the db, like so:
entry match {
case `entry` =>
if(db.table contains entry) {
true
}
false
}
FindInDB is called in another function, which is defined in a class called Service.
I want to be able to mock the db.table part. From reading scalatest I know I could mock the class that FindInDB is defined and control what the function that calls FindInDB returns, but I want to test the FindInDB function itself and control what is in db.table through mock
You can use DB mockup framework such as jOOQ, or my framework Acolyte. Acolyte can mock DB at JDBC level, for any project based one JDBC directly or indirectly (e.g. JPA, EJB, Anorm, Slick): you describe for each test case which JDBC result (resultset, update count, error) is for which statement.
It allows to mockup exactly the same JDBC data would be exchanges by your app/lib with expected DB, with many advantages for testing: unit isolation, simplicity (no need to setup/tear down test DB with fixtures).
Documentation is online at http://acolyte.eu.org/ .
There is a Scala DSL which is easily usable for testing (examples with specs are available in documentation).
Related
Can any one please help me in mocking db.GetCollection of MongoDatabase to return mocked data using Moq
//returns MongoDatabase instance
var db = mongoConnector.Connect();
//Return Collection on the type Entity being passed
db.GetCollection<Entity>("CollectionName").AsQueryable().ToList();
Unit testing MongoDatabase sounds like an overkill. I would strongly recommend having data dependent integration tests for your data access layer. Test your core CRUD code using integration tests and clean up/bootstrap the database after each test run. Cleaning up the database on teardown is important as every test should be independent of other.
MOQ can be used to test the business logic layer in which you can mock the data access layer and return expected data instead of hitting the database.
I have the following entity and it was not until run time that i realized that the table name annotation is incorrect.
How can i write unit tests to prevent this?
#Entity
#Table(name = "cache_server")
public class VirtualMachine implements Serializable {
}
It is not about unit testing here, but rather about integration testing, as you need a JPA provider to test it (with a DB server). And when it comes to integration tests, it is very specific to what technologies you use. If you are in Application Server, like Jboss, take a look at Arquillian.
UPDATE
Although I think that usually you do not want to unit test values in annotations, as they represent configuration data, you can always read the values in the annotations using some reflexion. See this question (directly in the question) for an example.
I'm working on my first Scala application, where we use an ActiveRecord style to retrieve data from MongoDB.
I have models like User and Category, which all have a companion object that uses the trait:
class MongoModel[T <: IdentifiableModel with CaseClass] extends ModelCompanion[T, ObjectId]
ModelCompanion is a Salat class which provide common MongoDB crud operations.
This permits to retrieve data like this:
User.profile(userId)
I never had any experience with this ActiveRecord query style. But I know Rails people are using it. And I think I saw it on Play documentation (version 1.2?) to deal with JPA.
For now it works fine, but I want to be able to run integration tests on my MongoDB.
I can run an "embedded" MongoDB with a library. The big deal is that my host/port configuration are actually kind of hardcoded on the MongoModel class which is extended by all the model companions.
I want to be able to specify a different host/port when I run integration tests (or any other "profile" I could create in the future).
I understand well dependency injection, using Spring for many years in Java, and the drawbacks of all this static stuff in my application. I saw that there is now a scala-friendly way to configure a Spring application, but I'm not sure using Spring is appropriate in Scala.
I have read some stuff about the Cake pattern and it seems to do what I want, being some kind of typesafe, compile-time-checked spring context.
Should I definitely go to the Cake pattern, or is there any other elegant alternative in Scala?
Can I keep using an ActiveRecord style or is it a total anti-pattern for testability?
Thanks
No any static references - using Cake pattern you got 2 different classes for 2 namespaces/environments, each overriding "host/port" resource on its own. Create a trait containing your resources, inherit it 2 times (by providing actual information about host/port, depending on environment) and add to appropriate companion objects (for prod and for test). Inside MongoModel add self type that is your new trait, and refactor all host/port references in MongoModel, to use that self type (your new trait).
I'd definitely go with the Cake Pattern.
You can read the following article with show an example of how to use the Cake Pattern in a Play2 application:
http://julien.richard-foy.fr/blog/2011/11/26/dependency-injection-in-scala-with-play-2-it-s-free/
I have a java class that implements serializable and the class begins with :
#NamedQueries( {
#NamedQuery(....)
#NamedQuery(....)
...
..})
My question is at what stage these queries are going to be executed because i see no direct call to these queries by their name
Project is using JPA. I think IBM implementation of JPA...surely not hibernate.
Thank you
Each named query has a name and the query is executed by invoking EntityManager.createnamedQuery().
If the name of the query is based on a constant, you can search the usages of the constant in your project or if it's just a string, you can a text search in your project.
If you don't find any usages, there's a chance that those queries are not used at all, unless there's another framework that is invoking them (by doing something like convention over configuration).
If you have a system that has multiple types of object contexts. For Eg: BillingObjectContext, HumanResourceObjectContext etc. All derive from ObjectContext but ObjectContext Class does not implement any specific interface like IObjectContext. How would you apply DI/IoC in case of multiple types of ObjectContext say using Ninject?
If you must depend on it in a test, you have to mock it. Here's a sample; it's not much harder than implementing an interface. See also TDD improvements in EF 4.
Why can't we just create the actual context object to be used in our tests? Since we don't want our tests to affect the production database, we can always specify a connection string that points to a test database. Before running each test, construct a new context, add the data you will need in your test, proceed with the unit test, then in the test cleanup section, delete all the records that were created during the test. The only side-affect here would be that the auto-increment IDs would be used up in the test database, but since it's a test database - who cares?
I know that most answers regarding this question propose using DI/IoC designs to create interfaces for data contexts etc. but the reason I am using Entity Framework is exactly to not write any interfaces for my database connections, object models, and simple CRUD transactions. To write mock interfaces for my data objects and to write complex queryable objects to support LINQ, defeats the purpose of relying on highly-tested and reliable Entity Framework.
This pattern for unit testing is not new - Ruby on Rails has been using it for a long time and it's worked out great. Just as .NET provides EF, RoR provides ActiveRecord objects and each unit test creates the objects it needs, proceeds with the tests, and then deletes all the constructed records.
How to specify connection string for test environment? Since all tests are in their own dedicated test project, adding a new App.Config file with a connection string for the test database would suffice.
Just think of how much headache and pain this will save you.
namespace ProjectNamespace
{
[TestClass]
public class UnitTest1
{
private ObjectContext objContext;
[TestInitialize]
public void SetUp()
{
// Create the object context and add all the necessary data records.
}
[TestMethod]
public void TestMethod1()
{
// Runs the tests.
}
[TestCleanup]
public void CleanUp()
{
// Delete created records.
}
}
}