How to create mock object of main class to have partial integration test using PlaySpec? - scala

There is a main class named 'MainProcess.scala' that I'm running some test cases for it. I wanno write an end to end test for this class to validate it's functionality.
Th problem here is the end to end test requires some criteria has to be established to be able to test whole functionality. For instance:
class MainProcess() {
def foo(someparams):Future[Boolean] = {
if criteria true else false
}
def bee(some params):Future[WSResponse] = {
// call a micro service
}
}
My question is: Is it a good practice to mock 'foo' method such that it always return true or mock 'bee' method so that test can pass through these modules and continue till it reaches the point I intend to see it's result. As I am testing this class, I know that mocking the same class results into error or malfunctionality of test case:
private def guiceApplicationBuilder(app: Application): Application = {
new GuiceApplicationBuilder()
.overrides(bind[MainProcess].toInstance(mainProcessMock))
.build()
}
If this is not a good practice, so how to do such stuff to mock specific modules of main class?
Thank you in advance.

Related

scala: Moking my scala Object that has external dependency

I have a Object like this:
// I want to test this Object
object MyObject {
protected val retryHandler: HttpRequestRetryHandler = new HttpRequestRetryHandler {
def retryRequest(exception: IOException, executionCount: Int, context: HttpContext): Boolean = {
true // implementation
}
}
private val connectionManager: PoolingHttpClientConnectionManager = new PoolingHttpClientConnectionManager
val httpClient: CloseableHttpClient = HttpClients.custom
.setConnectionManager(connectionManager)
.setRetryHandler(retryHandler)
.build
def methodPost = {
//create new context and new Post instance
val post = new HttpPost("url")
val res = httpClient.execute(post, HttpClientContext.create)
// check response code and then take action based on response code
}
def methodPut = {
// same as methodPost except use HttpPut instead HttpPost
}
}
I want to test this object by mocking dependent objects like httpClient. How to achieve this? can i do it using Mokito or any better way? If yes. How? Is there a better design for this class?
Your problem is: you created hard-to test code. You can turn here to watch some videos to understand why that is.
The short answer: directly calling new in your production code always makes testing harder. You could be using Mockito spies (see here on how that works).
But: the better answer would be to rework your production code; for example to use dependency injection. Meaning: instead of creating the objects your class needs itself (by using new) ... your class receives those objects from somewhere.
The typical (java) approach would be something like:
public MyClass() { this ( new SomethingINeed() ); }
MyClass(SomethingINeed incoming) { this.somethign = incoming; }
In other words: the normal usage path still calls new directly; but for unit testing you provide an alternative constructor that you can use to inject the thing(s) your class under test depends on.

Passing variables between Cucumber step definitions

In Cucumber, how do i go about passing variables between step definition classes. Im trying to implement in Scala.
Looking around I have seen people suggest using Guice or Picocontainer or any other DI framework. But have not really come across an example in Scala.
For instance for the example below how do I pass the variable using DI ?
Provider.scala,
class Provider extends ScalaDsl with EN with Matchers with WebBrowser {
......
When("""I click the Done button$""") {
val doneButton = getElement(By.id(providerConnectionButton))
doneButton.click()
}
Then("""a new object should be created successfully""") {
// Pass the provider ID created in this step to Consumer definition
}
}
Consumer.scala,
class Consumer extends ScalaDsl with EN with Matchers with WebBrowser {
......
When("""^I navigate to Consumer page$""") { () =>
// providerId is the id from Provider above
webDriver.navigate().to(s"${configureUrl}${providerId}")
}
}
You can use ThreadLocal to solve your problem
Here's code snippet for solution.
object IDProvider{
val providerId = new ThreadLocal[String]
def getProviderId: String = {
providerId.get()
}
def setProviderId(providerId: String): Unit = {
providerId.set(providerId)
}
}
To access providerID across different step definitions. You can simply call IDProvider.getProviderId
And to set the value of providerID, simply call IDProvider.setProviderId(PROVIDER_ID)

Scala design suggestion needed

I would like to design a client that would talk to a REST API. I have implemented the bit that actually does call the HTTP methods on the server. I call this Layer, the API layer. Each operation the server exposes is encapsulated as one method in this layer. This method takes as input a ClientContext which contains all the needed information to make the HTTP method call on the server.
I'm now trying to set up the interface to this layer, let's call it ClientLayer. This interface will be the one any users of my client library should use to consume the services. When calling the interface, the user should create the ClientContext, set up the request parameters depending on the operation that he is willing to invoke. With the traditional Java approach, I would have a state on my ClientLayer object which represents the ClientContext:
For example:
public class ClientLayer {
private static final ClientContext;
...
}
I would then have some constructors that would set up my ClientContext. A sample call would look like below:
ClientLayer client = ClientLayer.getDefaultClient();
client.executeMyMethod(client.getClientContext, new MyMethodParameters(...))
Coming to Scala, any suggestions on how to have the same level of simplicity with respect to the ClientContext instantiation while avoiding having it as a state on the ClientLayer?
I would use factory pattern here:
object RestClient {
class ClientContext
class MyMethodParameters
trait Client {
def operation1(params: MyMethodParameters)
}
class MyClient(val context: ClientContext) extends Client {
def operation1(params: MyMethodParameters) = {
// do something here based on the context
}
}
object ClientFactory {
val defaultContext: ClientContext = // set it up here;
def build(context: ClientContext): Client = {
// builder logic here
// object caching can be used to avoid instantiation of duplicate objects
context match {
case _ => new MyClient(context)
}
}
def getDefaultClient = build(defaultContext)
}
def main(args: Array[String]) {
val client = ClientFactory.getDefaultClient
client.operation1(new MyMethodParameters())
}
}

Unit Testing MVVMLight Messenger

Is it possible to write a Unit Test that calls the Messenger.Default.Register method and then write an Assertion to be used by the Action?
I would like to determine if my ViewModel is sending the correct message after calling an Execute on one of my Commands.
I have tried writing the Assert.AreEqual as the Action however this doesn't seem to be working correctly.
Sounds like a job for mocking! Assuming you're passing in the messenger interface to your viewmodel (because dependency inversion is a Good Thing, for this very reason), your code should look something like this if I understand you correctly:
public class YourViewModel
{
readonly IMessenger messenger;
public YourViewModel(IMessenger messenger)
{
this.messenger = messenger;
// setup of your delegate command to call Execute
}
void Execute(object parameter)
{
messenger.Send(new YourMessageType());
}
}
Then in your unit test you'd mock the messenger and verify that the right method is called, which in this case is Send. So, using the popular mocking framework Moq:
public class YourViewModelTests
{
[Test]
public void Execute_Always_SendsYourMessageType()
{
// arrange
var mockRepository = new MockRepository(MockBehavior.Loose);
var mockMessenger = mockRepository.Create<IMessenger>();
var systemUnderTest = new YourViewModel(mockMessenger.Object);
// act
systemUnderTest.YourCommand.Execute(null);
// assert
mockMessenger.Verify(p => p.Send<YourMessageType>(
It.Is(m => /* return true if it's the right message */)));
}
}
Usually I'd move the just about all of the "arrange" phase into a test setup method, but you should get the idea.
If you'd still like to do it without mocking the messenger and also use Messenger.Default, you can do the following:
public class YourViewModelTests
{
[Test]
public void Execute_Always_SendsYourMessageType()
{
// arrange
var systemUnderTest = new YourViewModel();
// Set the action to store the message that was sent
YourMessageType actual;
Messenger.Default.Register<YourMessageType>(this, t => actual = t);
// act
systemUnderTest.YourCommand.Execute(null);
// assert
YourMessageType expected = /* set up your expected message */;
Assert.That(actual, Is.EqualTo(expected));
}
}
Alternatively, for each test it is possible to create a separate copy of the Messenger. For the runtime you want to use the Default instance of the Messenger, but for Unit Tests, as I said, create a separate copy for each test:
return new GalaSoft.MvvmLight.Messaging.Messenger(); // Unit Tests
return GalaSoft.MvvmLight.Messaging.Messenger.Default; // Runtime
Otherwise one might end up re-inventing the wheel, since in more complex situations where there is a need to test ViewModel communications, you will have to manage Messenger subscribers, message types an so on. Then probably writing unit tests for the messenger mock making sure it works in the same way as the original messenger. There is nothing in the engine of the Messenger that should be different when comparing Runtime and Test executions.
So for testing a factory returns the same instance of the Messenger. Test method subscribes and waits, ViewModel publishes; then Test accepts and exits. Otherwise Test times out and reports an error. I found this approach more "closer to reality" than mocking the messenger and verifying through the mock that the method was called.

is there a scalaTest mechanism similar to TestNg dependsOnMethods annotation

Can I have dependencies between scalaTest specs such that if a test fails, all tests dependent on it are skipped?
I didn't add that feature of TestNG because I didn't at the time have any compelling use cases to justify it. I have since collected some use cases, and am adding a feature to the next version of ScalaTest to address it. But it won't be dependent tests, just a way to "cancel" a test based on an unmet precondition.
In the meantime what you can do is simply use Scala if statements to only register tests if the condition is met, or to register them as ignored if you prefer to see it output. If you are using Spec, it would look something like:
if (databaseIsAvailable) {
it("should do something that requires the database") {
// ...
}
it ("should do something else that requires the database") {
}
}
This will only work if the condition will be met for sure at test construction time. If the database for example is supposed to be started up by a beforeAll method, perhaps, then you'd need to do the check inside each test. And in that case you could say it is pending. Something like:
it("should do something that requires the database") {
if (!databaseIsAvailable) pending
// ...
}
it("should do something else that requires the database") {
if (!databaseIsAvailable) pending
// ...
}
Here is a Scala trait that makes all test in the test suite fail, if any test fails.
(Thanks for the suggestion, Jens Schauder (who posted another answer to this question).)
Pros: Simple-to-understand test dependencies.
Cons: Not very customizable.
I use it for my automatic browser tests. If something fails, then usually there's no point in continuing interacting with the GUI since it's in a "messed up" state.
License: Public domain (Creative Common's CC0), or (at your option) the MIT license.
import org.scalatest.{Suite, SuiteMixin}
import scala.util.control.NonFatal
/**
* If one test fails, then this traits cancels all remaining tests.
*/
trait CancelAllOnFirstFailure extends SuiteMixin {
self: Suite =>
private var anyFailure = false
abstract override def withFixture(test: NoArgTest) {
if (anyFailure) {
cancel
}
else try {
super.withFixture(test)
}
catch {
case ex: TestPendingException =>
throw ex
case NonFatal(t: Throwable) =>
anyFailure = true
throw t
}
}
}
I don't know about a ready made solution. But you can fairly easily write your own Fixtures.
See "Composing stackable fixture traits" in the javadoc of the Suite trait
Such a fixture could for example replace all test executions after the first one with calls to pending
You can use trait org.scalatest.CancelAfterFailure to cancel remaining tests after first failure:
import org.scalatest._
class MySpec extends FunSuite with CancelAfterFailure {
test("successfull test") {
succeed
}
test("failed test") {
assert(1 == 0)
}
test("this test and all others will be cancelled") {
// ...
}
}