Wednesday, March 10, 2021

Re: New Article "10 Best Java Frameworks to Use in 2021"

What i mean is that mockito make it very easy to mock things, that we end up mocking everything, have we seen tests that mock every argument going into the constructor? have we seen concrete implementation being mocked without introducing an abstraction level that opens the doors for other implementations? have wee seen code that ends up with hight coupling because we actually mocked things in the tests? I mean tests are a way to design not just to verify that code is working..this might be just my opinion but here is a small example - those are no exact conversion but they are the best I could find from the old code

@ExtendWith(MockitoExtension.class)
class SubmitIssuanceCheckRequestUseCaseTest {

@Mock
private ChecksRepository checksRepository;
@Mock
private EventPublisher eventPublisher;
@Mock
private IdentityProvider identityProvider;

@InjectMocks
private SubmitIssuanceCheckRequestUseCase submitIssuanceCheckRequestUseCase;

private String currentUserName = UUID.randomUUID().toString();

@BeforeEach
void setUp() {
when(identityProvider.currentIdentity().getName()).thenReturn(currentUserName);
}

@Test
void givenNull_whenExecute_thenShouldThrowException() {
String message = assertThrows(IllegalArgumentException.class,
() -> submitIssuanceCheckRequestUseCase.execute(null))
.getMessage();
assertThat(message).isEqualTo(CHECK_CANNOT_BE_NULL);
}

@Test
void givenStockCheck_whenExecute_thenShouldUpdateCheckStatusToIssued() {
Check check = new Check();
check.setStatus(CheckStatus.STOCK);
check.setReference(UUID.randomUUID().toString());

submitIssuanceCheckRequestUseCase.execute(check);

ArgumentCaptor<Check> captor = ArgumentCaptor.forClass(Check.class);
Mockito.verify(checksRepository).update(captor.capture());
assertThat(captor.capture().getStatus()).isEqualTo(CheckStatus.ISSUED);
assertThat(captor.capture().getReference()).isEqualTo(check.getReference());
assertThat(captor.capture().getIssuanceDate()).isNotNull();
assertThat(captor.capture().getIssuedBy()).isEqualTo(currentUserName);
}

@Test
void givenStockCheck_whenExecute_thenShouldPublishCheckIssuedEvent() {
Check check = new Check();
check.setStatus(CheckStatus.STOCK);
check.setReference(UUID.randomUUID().toString());

submitIssuanceCheckRequestUseCase.execute(check);

ArgumentCaptor<CheckEventEvent<Address>> captor = ArgumentCaptor.forClass(CheckEvent.class);
verify(eventPublisher).publish(captor.capture());
assertThat(captor.getValue().getHeader().getReference()).isEqualTo(check.getReference());
assertThat(captor.getValue().getHeader().getEventType()).isEqualTo(CHECK_ISSUED);
assertThat(captor.getValue().getBody().getPayload()).isEqualTo(check);
}
}



VS 

public class PostCheckUseCaseTest {
private PostCheckUseCase postCheckUseCase;

private Check validCheck;
private Check savedCheck;
private CheckEvent<Check> publishedEvent;
private Check publishedCheck;

@Before
public void setUp() {
postCheckUseCase = new PostCheckUseCase(
check -> this.savedCheck = check,
checkEvent -> this.publishedEvent = checkEvent,
check -> this.publishedCheck = check
);
validCheck = buildValidCheck();
}

private Check buildValidCheck() {

Check check = new Check();
check.setReference("ABCDEFGHIJKLMN");
check.setPostingType(PostingType.IMMEDIATE);
check.setStatus(CheckStatus.DEPOSITED);
check.setSubmissionDate(LocalDateTime.now());
UserDecisionLog userDecisionLog = new UserDecisionLog();
userDecisionLog.setPostingDecision(PostingDecision.INITIAL);
check.setUserDecision(Arrays.asList(userDecisionLog));

return check;
}

@Test
public void givenNullCheck_whenExecute_thenShouldThrowException() {
assertThatExceptionOfType(IllegalArgumentException.class)
.isThrownBy(() -> postCheckUseCase.execute(null))
.withMessage("check cannot be null");
}

@Test
public void givenValidCheck_whenExecute_thenShouldUpdateStatusWithDepositedAndSubmissionDateOnRepository() {
validCheck.setStatus(null);
validCheck.setPostingType(PostingType.IMMEDIATE);
Check postedCheck = postCheckUseCase.execute(validCheck);
assertThat(postedCheck.getStatus()).isEqualTo(CheckStatus.DEPOSITED);
assertThat(postedCheck.getSubmissionDate()).isEqualToIgnoringSeconds(LocalDateTime.now());
assertThat(getLastUserDecision(postedCheck).getPostingDecision()).isEqualTo(PostingDecision.POST_IMMEDIATELY);
assertThat(savedCheck).isEqualTo(postedCheck);
}

@Test
public void givenReceivedCheck_whenExecute_thenShouldPublishEvent() {
Check postedCheck = postCheckUseCase.execute(validCheck);

assertThat(publishedEvent.getHeader().getReference()).isEqualTo(postedCheck.getReference());
assertThat(publishedEvent.getHeader().getEventType()).isEqualTo(CheckStatus.DEPOSITED.getEventType());
assertThat(publishedEvent.getBody().getPayload()).isNotNull();
assertThat(publishedEvent.getBody().getPayload()).isSameAs(postedCheck);
}

@Test
public void givenRepresentedCheck_whenExecute_thenShouldPublishEvent() {
validCheck.setStatus(CheckStatus.REPRESENTED);
Check postedCheck = postCheckUseCase.execute(validCheck);
assertThat(publishedEvent.getHeader().getReference()).isEqualTo(postedCheck.getReference());
assertThat(publishedEvent.getHeader().getEventType()).isEqualTo(CheckStatus.REPRESENTED.getEventType());
assertThat(publishedEvent.getBody().getPayload()).isNotNull();
assertThat(publishedEvent.getBody().getPayload()).isSameAs(postedCheck);
}

@Test
public void givenValidCheck_whenExecute_thenShouldSendMessageToBank() {
Check postedCheck = postCheckUseCase.execute(validCheck);
assertThat(publishedCheck).isEqualTo(postedCheck);
}

private UserDecisionLog getLastUserDecision(Check validCheck) {
return validCheck.getUserDecision().get(validCheck.getUserDecision().size() - 1);
}

I have seen tests that way far more code just doing  ArgumentCaptor  or When(..).then(...) .. etc than any actual testing code.. it could go wildly bad...
I had to write tests in both styles to convince myself.. but I believe this will remain a topic with a debate. 
On Wednesday, March 10, 2021 at 5:56:20 PM UTC+2 gardella...@gmail.com wrote:
Hi Vegeoku,

Could you please elaborate on this?

IMHO tests should help you improve the design of your code, Mockito is the opposite of that, Once I converted some test cases to use manually writing test doubles (spies, fakes, stubs) instead of Mockito to show the other guy how it reduced the code in the test and improves the design. Mockito makes it super easy to look away from design issues.

Thanks,
Juan

P.S. Amazing thread.

On Wed, 10 Mar 2021 at 12:47, Josselin Bardet <nam...@gmail.com> wrote:


Le mer. 10 mars 2021 à 16:42, Vegegoku <aka...@gmail.com> a écrit :


Spring: I think the thing I dislike the most about Spring is what many people like about it: it's an entire, wide, and fat, ecosystem. You can hardly use one piece of Spring without using everything else; I mean, each Spring piece builds on top of another Spring piece, so it's basically an all-or-nothing. I also fear that people doing mostly Spring won't know how to do things without it (like most big/fat framework actually).


That does really summaries it about spring, also I hate how it is being overused for simple projects,  Like sucking this huge ecosystem just because we need dependency injection or want to talk to the database (JPA -> spring data) and it ends up building a huge complexity instead of simplifying things.. (Tests for example), I once want to contribute to a project that was using spring to find out that I had to inject a single bean into 500+ other classes using the constructor where even the arguments were not arranged to make this any easier and while doing that I had to fight merge conflicts .. it is overrated and overused .. and I pretty sure that most of spring project developer relay too much on mocking to make the tests faster or avoid such dependency injection hell.
 

Spring is well tested and works well, can handle your transctions, can help you to make AOP, can make dependency injection, etc...
Spring is for me a killer feature, I can't imagine making a project, even simple, without using it.

I don't think nowadays there is a good reason to "optimize" and don't use spring

--
You received this message because you are subscribed to the Google Groups "GWT Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-web-tool...@googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "GWT Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-web-toolkit+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/google-web-toolkit/605271a7-3edf-4fac-bd8c-f91602854c47n%40googlegroups.com.

No comments:

Post a Comment