How to unit test code blocks in spring boot - spring-boot

I have unit test in spring boot written using junit and mockito . I have method that has uses method which take code block as input and perform required function . Below is sample example of code.
class A{
execute(Codeblock codeblock){
}
}
Class B {
C testFunction(){
return A.execute(()->{
code to execult ...;
});
}
}
class TestB{
#InjectMock
B b;
#Mock
A a;
void testFunction(){
when(A.execult(any())).return(C);
AssertNotNull(b.testFunction());
}
}
This code is running fine but code coverage is very low because code block is not execute. Is there any way to execute code block and increase coverage.

Testing your class (B) using mocks (A) is correct, the goal is to test any logic in B and verify the interactions with the collaborators (in this case A).
I would then create test for A (mocking Codeblock class), applying the same principle as above.
Finally I would test Codeblock logic independently.

Related

Mocking is sometimes not applied when running a multi-class testsuite

I am testing a service which heavily relies on project reactor.
For many tests I am mocking the return value of the component responsible for API calls.
The tests are split over multiple files.
When I run the tests of one file, they are green, but when I execute all of the test files at once, some tests fail, with the error message indicating that the mocking did not succeed (Either the injected component returned null, or the implementation of the actual component is invoked).
In the logs, there is no information about the mocking failing.
A code example:
interface API {
Flux<Bird> getBirds();
}
#Component
class BirdWatcher {
API api;
BirdWatcher(API api) {
this.api = api;
}
Flux<Bird> getUncommonBirds() {
return api.getBirds() // Although this is mocked in the test, in some runs it returns `null` or calls the implementation of the actual component
.filter(Bird::isUncommon);
}
}
#SpringBootTest
class BirdWatcherTests {
#Autowired
BirdWatcher birdWatcher;
#MockBean
API api;
#Test
void findsUncommonBirds() {
// Assemble
Bird birdCommon = new Bird("Sparrow", "common");
Bird birdUncommon = new Bird("Parrot", "uncommon");
Mockito.when(api.getBirds()).thenReturn(Flux.just(birdCommon, birdUncommon));
// Act
Flux<Bird> uncommonBirds = birdWatcher.getUncommonBirds();
// Assert
assertThat(uncommonBirds.collectList().block().size(), equalTo(1));
}
}
For me the issue seems like a race condition, but I don't know where and how this might happen, and how I can check and fix this.
I am using spring-boot-test:2.7.8, pulling in org.mockito:mockito-core:4.5.1 org.mockito:mockito-junit-jupiter:4.5.1, and org.junit.jupiter:junit-jupiter:5.8.2, with gradle 7.8.
For reactor, spring-boot-starter-webflux:2.7.8, depending on reactor:2.7.8.

Integration or unit test

It is not quite clear to me when I should use integrations and unit test
If I want to test the following code without making any http requests, should I use an integration test or unit ?
When a thread is created, the activity is recorded and an email event is fired
ThreadObserver extends Observer
{
public function created(Thread $thread)
{
Activity::record($thead);
event(new ThreadWasCreated($thread);
}
}
class RecordsActivityTest
{
public function it_records_the_acitivty_when_a_thread_is_created()
{
Thread::factory()->create();
$this->assertDatabaseHas('activities', […]);
}
}
Another example, I want to test that give a query it returns the expected results .
class Search
{
public function __construct(protected Index $index)
{
}
public function handle($query)
{
$this->index->search($query);
// more code
}
}
class SearchTest
{
public function it_returns_the_expected_result()
{
$search = new Search(new Index);
$results = $search->handle(“some query”);
$this->assertEquals(“some
Data”);
}
}
Do I need a unit test, to test the Search class or an integration test because it is dependent on another class ?
The first example, I'd most likely write an integration test, but instead of testing if the database has a value, I'd just mock the event https://laravel.com/docs/8.x/mocking#event-fake and assert that the event was dispatched.
The second example however, it could go either way. You can write a unit test and just mock everything OR, you could write an integration test so you can use the Laravel helpers, specifically the https://laravel.com/docs/8.x/mocking#http-fake if you're testing an API, otherwise mockery if you're testing and SDK for example.

How to Unit test Service & controller (kotlin) in a Cordapp?

I have gone through many documentations for getting a sample of unit testing service and controller in a Cordapp, not the flows (that is already done using in corda docs). Can anyone please help me to get an example cordapp which implemented service unit testing?
Try taking a look at the CordaService Autopayroll sample on github.
link: https://github.com/corda/samples-java/tree/master/Features/cordaservice-autopayroll
There's an ability to access registered services that gets used here in the testing code
//Test #1 check if the requestState is being sent to the bank operator behind the scene.
#Test
fun `dummy test`() {
val future = a.startFlow(RequestFlowInitiator("500", b.info.legalIdentities.first()))
network.runNetwork()
val ptx = future.get()
println("Signed transaction hash: ${ptx.id}")
listOf(a, bank).map {
it.services.validatedTransactions.getTransaction(ptx.id)
}.forEach {
val txHash = (it as SignedTransaction).id
println("$txHash == ${ptx.id}")
assertEquals(ptx.id, txHash)
}
}
link: https://github.com/corda/samples-kotlin/blob/master/Features/cordaService-autopayroll/workflows-kotlin/src/test/kotlin/net/corda/examples/autopayroll/FlowTests.kt
Good luck!
We can use Mockito module for mocking and stabbing that is required for unit testing service functions and APIs.
This link will direct more on how to mock CordaRPCops using mockito as an example.

How do I write a unit test for a Flutter method that completes later with a future?

I'm writing a unit test for a Flutter method that calls an async method and then returns, leaving the async to complete as and when. My test fails "after it had already completed".
Here's my test:
test('mark as viewed', () {
final a = Asset();
expect(a.viewed, false);
a.markAsViewed();
expect(a.viewed, true);
});
and here's the method it's testing:
void markAsViewed() {
viewed = true;
Repository.get().saveToStorage();
}
The saveToStorage() method is an async that I just leave to execute in the background.
How do I make this work? The test failure tells me Make sure to use [expectAsync] or the [completes] matcher when testing async code. but I can't see how to do that. Can anyone explain or else point me to the right documentation please? I can't find anything about how to handle these asyncs when it's not a Future that's being returned, but just being left to complete separately.
To be clear - this unit test isn't about testing whether it's saved to storage, just a basic test on setting viewed to be true.
Edited
The error is as follows:
package:flutter/src/services/platform_channel.dart 319:7 MethodChannel.invokeMethod
===== asynchronous gap ===========================
dart:async _asyncErrorWrapperHelper
package:exec_pointers/asset_details.dart Repository.saveToStorage
package:exec_pointers/asset_details.dart 64:22 Asset.markAsViewed
test/asset_details_test.dart 57:9 main.<fn>.<fn>
This test failed after it had already completed. Make sure to use [expectAsync]
or the [completes] matcher when testing async code.
This code is tightly coupled to implementation concerns that make testing it in isolation difficult.
It should be refactored to follow a more SOLID design with explicit dependencies that can be replaced when testing in isolation (unit testing)
For example
class Asset {
Asset({Repository repository}) {
this.repository = repository;
}
final Repository repository;
bool viewed;
void markAsViewed() {
viewed = true;
repository.saveToStorage();
}
//...
}
That way when testing a mock/stub of the dependency can be used to avoid any unwanted behavior.
// Create a Mock Repository using the Mock class provided by the Mockito package.
// Create new instances of this class in each test.
class MockRepository extends Mock implements Repository {}
main() {
test('mark as viewed', () {
final repo = MockRepository();
// Use Mockito to do nothing when it calls the repository
when(repo.saveToStorage())
.thenAnswer((_) async => { });
final subject = Asset(repo);
expect(subject.viewed, false);
subject.markAsViewed();
expect(subject.viewed, true);
//
verify(repo.saveToStorage());
});
}
The test should now be able to be exercised without unexpected behavior from the dependency.
Reference An introduction to unit testing
Reference Mock dependencies using Mockito
Reference mockito 4.1.1

PowerMockito testing for rabbitmq akka streams

I am writing some testcases using RabbitMq library provided by
io.scalac.amqp
The testcase is to test consume message scenario, the code for which is something like and runs fine.
Source<Object, NotUsed> src = Source.fromPublisher(conn.consume(props.getQueue(), 1, false)).map(msg -> {
//some transformation to `ByteString` from "`Delivery`" msg
}
conn above is io.scalac.amqp.impl.RabbitConnection passed as io.scalac.amqp.impl.Connection
Parent class io.scalac.amqp.impl.Connection returns Publisher<Delivery>
while io.scalac.amqp.impl.RabbitConnection returns QueuePublisher
I write the testcase using PowerMock and spy Source class and mock like this
Source<Delivery,NotUsed> del;//Creating this object before calling the test
PowerMockito.spy(Source.class);
PowerMockito.when(Source.fromPublisher(Mockito.isA(Publisher.class))).thenReturn(del);
//Also tried
//PowerMockito.when(Source.fromPublisher(Mockito.isA(QueuePublisher.class))).thenReturn(del);
Is there any way I can test the consuming code through mocks?

Resources