I have a class which needs to be unit tested. The structure is as follows:
public class classToBeTested{
public returnType function1(){
//creation of variable V
return new classA(V).map();
}
}
The class classA is as follows:
public class classA{
//Constructor
public returnType map(){
//Work
}
}
I am creating unit tests in Scala using FunSuite, GivenWhenThen and EasyMock.
My test structure is as follows:
class classToBeTested extends FunSuite with GivenWhenThen with Matchers with EasyMockSugar {
test(""){
Given("")
val c = new classToBeTested()
expecting{
}
When("")
val returnedResponse = c.function1()
Then("")
//checking the returned object
}
}
What do I need to write in expectation?
How can I handle the above scenario?
Note: PowerMock can't be used.
Answer:
Thanks, #Henri. After a lot of searching and the answer provided by #Henri refactoring the code is the best way to handle this situation. Reason below:
The unit test cannot mock the objects that are created by the new call(without PowerMock). And hence to test the code, we need to write the unit tests according to the conditions present in the class being used(here classA) in the class to be tested(here classToBeTested). Hence while testing classToBeTested, we need to be aware of the functioning and structure of classA and create the test cases respectively.
As now the test cases are dependent on the structure of methods in classA, implying that classToBeTested and classA are tightly coupled. And hence by TDD approach, we need to refactor the code.
In the example above:
rather than using
classA object = new classA(V);
it's better to provide the object to the method(eg: Autowiring the classA object in Spring MVC).
Open to suggestions. Also if somebody could give a better explanation please do that.
You can't. The instantiation of what you want to mock is in the class you want to test. So without powermock, you need refactoring to make it work.
The minimum would be to extract the class creation into another method
public class classToBeTested{
public returnType function1(){
//creation of variable V
return getClassA(V).map();
}
protected classA getClassA(VClass v) {
return new classA(v);
}
Then, you can do a partial mock. I don't know how to do it in scala, so the code below is probably wrong but I hope you will get the idea.
class classToBeTested extends FunSuite with GivenWhenThen with Matchers with EasyMockSugar {
test(""){
Given("")
val c = partialMockBuilder(classToBeTested.class).addMockedMethod("getClassA").build()
val a = mock(classA.class)
expecting{
expect(c.getClassA()).andReturn(a)
expect(a.map()).andReturn(someReturnType)
}
When("")
val returnedResponse = c.function1()
Then("")
//checking the returned object
// whatever you need to check
}
}
Related
I would like implement a Guice module which binds an adapter to a named argument, but to create this adapter, it needs to instantiate another class, which also need injected arguments.
Here is the example in Scala:
trait Service
class UserService #Inject()(#Named(value = "foo") foo: String) extends Service
trait Adapter
class AdapterImpl(service: Service) extends Adapter
class AdapterRef(val adapter: Adapter)
class Module extends AbstractModule {
override def configure(): Unit = {
val fooValue = "bar"
bind(classOf[String])
.annotatedWith(Names.named("foo"))
.toInstance(fooValue)
val userService = new UserService(fooValue) //It should be instantiated by Guice somehow
bind(classOf[AdapterRef])
.annotatedWith(Names.named("userService"))
.toInstance(new AdapterRef(new AdapterImpl(userService))) //Thats kinda ok
}
}
Can someone point me to the right direction?
Thank you,
Gabor
You can use a Provides method within your module, which lets you remove the binding. This is my best effort at Scala so if the syntax is incorrect let me know.
#Provides() #Singleton() def provideAdapterRef(service: Service): AdapterRef = {
return new AdapterRef(new AdapterImpl(service))
}
Note the use of Singleton to imitate your examples use of toInstance. If you don't need it to always provide the same instance I would recommend removing the scope and letting it create a new one every time.
An alternative solution is to use a Provider. This requires you to keep a modified version of the binding in your module and create an extra class, but it can be a cleaner solution if your Provider is more complex.
//Can inject UserService as well, or provide annotations to configure which
//implementation of Service you get if you have more than one.
class UserServiceProvider #Inject()(service: Service) extends Provider[AdapterRef] {
override def get(): AdapterRef {
return new AdapterRef(new AdapterImpl(service))
}
}
Then you can change your binding in the module to
bind(classOf[AdapterRef])
.annotatedWith(Names.named("userService"))
.toProvider(classOf[UserServiceProvider])
.in(classOf[Singleton])
Here note the use of in(Singleton) to replicate your toInstance behavior.
This is kind of a weird use-case and I need some help in figuring out how to use Assisted/Providers/FactoryModuleBuilders in conjunction with each other. Ignore the absence of #Singleton. This is just an example.
A set of traits belonging to a library I cannot change have the following pattern. It uses Cake Pattern.
trait A { //Has abstract methods and abstract service 'webService' }
trait B extends A { //First Concrete Service Implementation assigned to 'webService' }
trait C extends A { //Second Concrete service Implementation assigned to 'webService' }
Since the traits cannot be directly injected, I created a wrapper that would allow them to be injected
BB extends B
CC extends C
In my code, I have a Controller that depends on a Service, that in turn depends on the library. The service should be able to either use "BB" or "CC" depending on what the controller needs. So the components look like the following
I create my service as
//Note: Uses 'trait A' with #Assisted
class SomeWebServiceComponent #Inject()(#Assisted aInstance: A, foo: Foo){
//Do something with aInstance
}
The Factory to create this (should be created by Guice by using FactoryModuleBuilder)
class SomeServiceFactory {
def getWebServiceComponent(a:A) SomeWebServiceComponent
}
The FactoryModule will look something like this
class ApplicationModule extends AbstractModule {
override def configure() = {
install(new FactoryModuleBuilder().build(classOf[SomeServiceFactory]))
}
}
I don't mind annotating the controllers with the actual classes that I need.
class OneController #Inject()(factory: SomeServiceFactory, bb: BB) extends Controller {
val webServiceComponent = factory.getWebServiceComponent(bb)
}
class AnotherController #Inject()(factory: SomeServiceFactory, cc: CC) extends Controller {
val webServiceComponent = factory.getWebServiceComponent(cc)
}
With this setup, I get errors of the following kind
No implementation for 'A' annotated with #com.google.inject.assistedinject.Assisted(value=) was bound
I need to understand how I can tell Guice that there are two implementations for Trait A, namely, BB and CC and the choice will be supplied at runtime.
Is there a way to achieve this use-case?
Ok, I created a separate project to test this whole scenario.
And it works the way the question is framed.
It turns out, the test cases that I were using, were not currently using GuiceInjection directly. The error message was however, so specifically related to GuiceInjection that I never investigated if the test setup was correct.
Changing the test base, resolved the issue.
I'm working with a project which already has some legacy code written in Scala. I was given a task to write some unit tests for one of its classes when I discovered it's not so easy. Here's the problem I've encountered:
We have an object, say, Worker and another object to access the database, say, DatabaseService which also extends other class (I don't think it matters, but still). Worker, in its turn, is called by higher classes and objects.
So, right now we have something like this:
object Worker {
def performComplexAlgorithm(id: String) = {
val entity = DatabaseService.getById(id)
//Rest of the algorithm
}
}
My first though was 'Well, I can probably make a trait for DatabaseService with the getById method'. I don't really like the idea to create an interface/trait/whatever just for the sake of testing because I believe it doesn't necessarily lead to a nice design, but let's forget about it for now.
Now, if Worker was a class, I could easily use DI. Say, via constructor like this:
trait DatabaseAbstractService {
def getById(id: String): SomeEntity
}
object DatabaseService extends SomeOtherClass with DatabaseAbstractService {
override def getById(id: String): SomeEntity = {/*complex db query*/}
}
//Probably just create the fake using the mock framework right in unit test
object FakeDbService extends DatabaseAbstractService {
override def getById(id: String): SomeEntity = {/*just return something*/}
}
class Worker(val service: DatabaseService) {
def performComplexAlgorithm(id: String) = {
val entity = service.getById(id)
//Rest of the algorithm
}
}
The problem is, Worker is not a class so I can't make an instance of it with another service. I could do something like
object Worker {
var service: DatabaseAbstractService = /*default*/
def setService(s: DatabaseAbstractService) = service = s
}
However, it scarcely makes any sense to me since it looks awful and leads to an object with mutable state which doesn't seem very nice.
The question is, how can I make the existing code easily testable without breaking anything and without making any terrible workarounds? Is it possible or should I change the existing code instead so that I could test it easier?
I was thinking about using extending like this:
class AbstractWorker(val service: DatabaseAbstractService)
object Worker extends AbstractWorker(DatabaseService)
and then I somehow could create a mock of Worker but with different service. However, I didn't figure out how to do it.
I'd appreciate any advice as to how either change the current code to make it more testable or test the existing.
If you can alter the code for Worker, you can change it to still allow it to be an object and also allow for swapping of the db service via an implicit with a default definition. This is one solution and I don't even know if this is possible for you, but here it is:
case class MyObj(id:Long)
trait DatabaseService{
def getById(id:Long):Option[MyObj] = {
//some impl here...
}
}
object DatabaseService extends DatabaseService
object Worker{
def doSomething(id:Long)(implicit dbService:DatabaseService = DatabaseService):Option[MyObj] = {
dbService.getById(id)
}
}
So we set up a trait with concrete impl of the getById method. Then we add an object impl of that trait as a singleton instance to use in the code. This is a good pattern to allow for mocking of what was previously only defined as an object. Then, we make Worker accept an implicit DatabaseService (the trait) on it's method and give it a default value of the object DatabaseService so that regular use does not have to worry about satisfying that requirement. Then we can test it like so:
class WorkerUnitSpec extends Specification with Mockito{
trait scoping extends Scope{
implicit val mockDb = mock[DatabaseService]
}
"Calling doSomething on Worker" should{
"pass the call along to the implicit dbService and return rhe result" in new scoping{
mockDb.getById(123L) returns Some(MyObj(123))
Worker.doSomething(123) must beSome(MyObj(123))
}
}
Here, in my scope, I make an implicit mocked DatabaseService available that will supplant the default DatabaseService on the doSomething method for my testing purposes. Once you do that, you can start mocking out and testing.
Update
If you don't want to take the implicit approach, you could redefine Worker like so:
abstract class Worker(dbService:DatabaseService){
def doSomething(id:Long):Option[MyObj] = {
dbService.getById(id)
}
}
object Worker extends Worker(DatabaseService)
And then test it like so:
class WorkerUnitSpec extends Specification with Mockito{
trait scoping extends Scope{
val mockDb = mock[DatabaseService]
val testWorker = new Worker(mockDb){}
}
"Calling doSomething on Worker" should{
"pass the call along to the implicit dbService and return rhe result" in new scoping{
mockDb.getById(123L) returns Some(MyObj(123))
testWorker.doSomething(123) must beSome(MyObj(123))
}
}
}
In this way, you define all the logic of importance in the abstract Worker class and that's what you till focus your testing on. You provide a singleton Worker via an object that is used in the code for convenience. Having an abstract class let's you use a constructor param to specify the database service impl to use. This is semantically the same as the previous solution but it's cleaner in that you don't need the implicit on every method.
This is in the context of Play framework. I have a controller that instantiates a Validator. Validator has validate method. Controller has a method putEnity() that validates the payload it receives using this validate().
For unit testing the controller, i would like to mock the call Validator.validate(). TestController looks like this
class EntityControllerTest extends FlatSpec with Mockito {
def testPutEntity() = {
val payload = createPayload()
val mockValidator = mock[Validator]
when(mockValidator.validate(anyString, anyString)).thenReturn(EntityValidationResult(true, "Test"))
EntityController.putEntity(payload)
}
The problem is that, this mock call is not being used but the actual validate() is called and hence the test fails.
How can i fix this
The problem is that in your final line:
EntityController.putEntity(payload)
you are effectively calling a static method on EntityController, and despite all your attempts to configure a mock Validator you've never had an opportunity to "inject it" into the controller.
It's going to be a little bit difficult to suggest an ideal solution without seeing how you've implemented your controller, but at a guess, you'd want to do something like the following to allow a mocked Validator to be injected for testing, but for everything else to work like before.
I'll step through it to (hopefully) make it clearer:
Step 1 - make EntityController instantiable:
You've probably got something like this:
object EntityController extends Controller {
...
def putEntity = Action ...
..
}
Replace it with this:
class EntityControl extends Controller {
...
def putEntity = Action ...
...
}
object EntityController extends EntityControl
Now you've given yourself the ability to new something with the same behaviour as your "production" object. But we need to be able to substitute in a mock validator...
Step 2 - require a validator instance in your EntityControl:
Your old EntityController object probably had something like this:
object EntityController extends Controller {
val validator = new Validator(...)
...
}
which is why you could never get your mocked validator involved. Let's inject it as a constructor parameter so it can't be forgotten:
class EntityControl(val validator:Validator) extends Controller {
...
}
object EntityController extends EntityControl(new Validator(...))
So again, our "production" EntityController object has all the functionality we used to have, but the key difference is that we've exposed a "testing seam" to allow a mock to be injected when needed.
Step 3 - inject, and test!
Flip to your test spec, and set up a testable EntityControl instance
class EntityControllerTest extends FlatSpec with Mockito {
def testPutEntity() = {
val payload = createPayload()
val mockValidator = mock[Validator]
when(mockValidator.validate(anyString, anyString)).thenReturn(EntityValidationResult(true, "Test"))
val myTestableEC = new EntityControl(mockValidator)
myTestableEC.putEntity(payload)
}
As you develop more test cases, you'll probably want to extract the setup-and-wiring parts of the test into a suitable function, or even a Specs2 Scope.
Hope this helps, and clarifies a few effective unit testing ideas for you too.
I'm developing a Play! 2.2 application in Scala with Slick 2.0 and I'm now tackling the data access aspect, trying to use the Cake Pattern.
It seems promising but I really feel like I need to write a huge bunch of classes/traits/objects just to achieve something really simple. So I could use some light on this.
Taking a very simple example with a User concept, the way I understand it is we should have:
case class User(...) //model
class Users extends Table[User]... //Slick Table
object users extends TableQuery[Users] { //Slick Query
//custom queries
}
So far it's totally reasonable. Now we add a "Cake Patternable" UserRepository:
trait UserRepository {
val userRepo: UserRepository
class UserRepositoryImpl {
//Here I can do some stuff with slick
def findByName(name: String) = {
users.withFilter(_.name === name).list
}
}
}
Then we have a UserService:
trait UserService {
this: UserRepository =>
val userService: UserService
class UserServiceImpl { //
def findByName(name: String) = {
userRepo.findByName(name)
}
}
}
Now we mix all of this in an object :
object UserModule extends UserService with UserRepository {
val userRepo = new UserRepositoryImpl
val userService = new UserServiceImpl
}
Is UserRepository really useful? I could write findByName as a custom query in Users slick object.
Let's say I have another set of classes like this for Customer, and I need to use some UserService features in it.
Should I do:
CustomerService {
this: UserService =>
...
}
or
CustomerService {
val userService = UserModule.userService
...
}
OK, those sound like good goals:
Abstract over the database library (slick, ...)
Make the traits unit testable
You could do something like this:
trait UserRepository {
type User
def findByName(name: String): User
}
// Implementation using Slick
trait SlickUserRepository extends UserRepository {
case class User()
def findByName(name: String) = {
// Slick code
}
}
// Implementation using Rough
trait RoughUserRepository extends UserRepository {
case class User()
def findByName(name: String) = {
// Rough code
}
}
Then for CustomerRepository you could do:
trait CustomerRepository { this: UserRepository =>
}
trait SlickCustomerRepository extends CustomerRepository {
}
trait RoughCustomerRepository extends CustomerRepository {
}
And combine them based on your backend whims:
object UserModuleWithSlick
extends SlickUserRepository
with SlickCustomerRepository
object UserModuleWithRough
extends RoughUserRepository
with RoughCustomerRepository
You can make unit-testable objects like so:
object CustomerRepositoryTest extends CustomerRepository with UserRepository {
type User = // some mock type
def findByName(name: String) = {
// some mock code
}
}
You are correct to observe that there is a strong similarity between
trait CustomerRepository { this: UserRepository =>
}
object Module extends UserRepository with CustomerRepository
and
trait CustomerRepository {
val userRepository: UserRepository
import userRepository._
}
object UserModule extends UserRepository
object CustomerModule extends CustomerRepository {
val userRepository: UserModule.type = UserModule
}
This is the old inheritance/aggregation tradeoff, updated for the Scala world. Each approach has advantages and disadvantages. With mixing traits, you will create fewer concrete objects, which can be easier to keep track of (as in above, you only have a single Module object, rather than separate objects for users and customers). On the other hand, traits must be mixed at object creation time, so you couldn't for example take an existing UserRepository and make a CustomerRepository by mixing it in -- if you need to do that, you must use aggregation. Note also that aggregation often requires you to specify singleton-types like above (: UserModule.type) in order for Scala to accept that the path-dependent types are the same. Another power that mixing traits has is that it can handle recursive dependencies -- both the UserModule and the CustomerModule can provide something to and require something from each other. This is also possible with aggregation using lazy vals, but it is more syntactically convenient with mixing traits.
Check out my recently published Slick architecture cheat sheet. It does not abstract over the database driver, but it is trivial do change it that way. Just wrap it in
class Profile(profile: JdbcProfile){
import profile.simple._
lazy val db = ...
// <- cheat sheet code here
}
You do not need the cake pattern. Just put it all in one file and you get away without it. The cake pattern allows you to split the code into different files, if you are willing to pay the syntax overhead. People also use the cake pattern to create different configurations including different combinations of services, but I don't think this is relevant to you.
If the repeated syntax overhead per database table bothers you, generate the code. The Slick code-generator is customizable exactly for that purpose:
If you want to blend hand-written and generated code, either feed the hand-written code into the code-generator or use a scheme, where the generated code inherits from hand-written cor vise-versa.
For replacing Slick by something else, replace the DAO methods with queries using another library.