👻

【初心者向け 093】SCSSの基礎文法一覧/SpringBootテスト2

2023/09/28に公開

SCSS

SCSSとは

scssは、cssの拡張版みたいな言語です。しかし、ブラウザーからはscssを理解することができないため、sassを利用して、ブラウザーが理解できるcssコードに変換する必要があります。

scssは、cssをプログラム言語のように活用できる言語で、NESTING,MIX-IN,EXTENDなどがあります。

cssから変数を設定することができますが、そういったカスタム変数もSCSSで支援した機能です。

cmd(Macならterminal)から上記のcommandを入力すれば、sassをインストールすることができます。

事前準備

まずは、既存のstyle.cssをstyle.scssに変更します。
(stylesというフォルダーに入れました。)

その後、npm run devを入力すれば、準備完了です。

$

現在のCSSはカスタム変数機能を提供しています。

/* ver css*/

:root{
  --bgColor:red;
}
.
.
body{
background-color:var(--bgColor);

SCSSでは、$という記号を付けることで変数を指定する宣言することができます。

/* ver scss*/

$bgColor:blue;

body{
background-color:$bgColor;
}

build

前述したとおり、ブラウザーはscssをコードを理解できないので、viteからscssをcssにコンパイルする必要があります。

まずはcmdから既存のサーバーを中止するため、ctrl + cを入力します。
それからcmdに**npm run build** を入力すれば、いかのようなフォルダーが生成されます。

distというフォルダー(distribute)から先ほどscssに宣言した変数がcssに変換されていることが分かります。

SCSSの文法

Nesting

一つの要素にスタイリングをする際は必然的に長いcssになります。

```css

このような長いコードをscssのNestingから短くすうことができます。

ルートは二つです。

Nestingはcomponentsのcssを作成する際に便利です。

@extends

@extendsを通して、styleをクラス化することができます。

 <span class="success">it's all good!</span>
 <span class="warning">Careful!</span>
<span class="error">Oh no! Something went wrong!</span>

こちらの<span>elementに同じスタイルを適用したい場合、scssを活用してコードを減らすことができます。


%alert{
  border-radius: 10px;
  border: 1px dashed black;
}


.success{
  @extend %alert;
  background-color: green;
}
.warning{
  @extend %alert;
  background-color:red;
}
.error{
  @extend %alert;
  background-color: yellow;
}

%alertに定義したdashed, border-radiusが適用されたことが分かります。

.error,
.warning,
.success {
  margin: 10px;
  padding: 10px 20px;
  border-radius: 10px;
  border: 1px dashed black;
}
.success {
  background-color: green;
}
.warning {
  background-color: red;
}
.error {
  background-color: #ff0;
}

変換したcssは以下のように変換されています。
%alertは消えています。

Mixins

先ほどのレイアウトはmixinsというアノテーションをとおしても表現することができます。
プログラミングの関数みたいな形です。

@mixinはfunctionと同じ動作し、@includeは関数を呼び出すためのアノテーションです。

@mixin alert($bgColor) {
  background-color: $bgColor;
  margin: 10px;
  padding: 10px 20px;
  border-radius: 10px;
  border: 1px dashed black;
}

.success {
  @include alert(green);
}
.warning {
  @include alert(red);
}
.error {
  @include alert(yellow);
}

Responsive Mixins

先ほどのspan classにcontentを追加したい場合、以下のよに宣言できます。セミコーロンを消し、ブロックを追加します。


/*Before*/
.error {
  @include alert(yellow);
}

/*After*/
.error {
  @include alert(yellow){
    font-size:12px;
  }
}
@mixin alert($bgColor) {
  .
  .
  .
  
  @content;
}

その後、上段のmixin 関数(説明のため、関数だと表現します。)
に@content;というアノテーションを追加すれば、span classのブロック内のcontentが追加されます。

先ほどの原理を活用し、@mixinにmedia queryを追加してみます。

$breakpoint-sm: 480px;
.
.
.

@mixin smallDevice {
  @media screen and (min-width: $breakpoint-sm) {
    @content;
  }
}
.
.
.

body{
  @include smallDevice{
      background-color: blue;
   } 
   .
   .
   .
}

4つのサイズによって異なるカラーになるとうにscssを適用した結果です。

SpringBoot

はじめに

Infleanから勉強した内容を紹介するため、画像の場合はスクラップしました。リンクはこちらです。
https://www.inflearn.com/course/스프링-입문-스프링부트/dashboard

springboot test2

https://zenn.dev/eldorado215/articles/463295ae7e94ed

先日作成したServiceクラスのテストクラスを作成します。

class MemberServiceTest {

    MemberService memberService = new MemberService();

    @Test
    void 会員登録() {
        //given
        Member member = new Member();
        member.setName("hello");

        //when
        Long saveId = memberService.join(member);

        //then
        Member findMember = memberService.findOne(saveId).get();
        Assertions.assertThat(member.getName()).isEqualTo(findMember.getName());

    }

テストメソッドの場合、外国人とのプロジェクトでhなない限り、母語で作成しても構わないです!テストクラスはBUILD時にメモリ上に上がらないようです!

相変わらず、コードのレベルが違過ぎて難しいですね!

次は、既存のサービスクラスにないメソッドを作成してみます。会員登録で、例外が生じる場合も想定して同一なIDの会員があるか照会するメソッドです。

    @Test
    void 중복_회원_예외(){
    //given
    Member member1 = new Member();
    member1.setName("spring");

    Member member2 = new Member();
    member2.setName("spring");

    //when
    memberService.join(member1);
    try {
         memberService.join(member2);
	 
//memberService.join(member2)の次はcatchに入ることが正しいロジックなので、次のラインに入ればfailです!

   fail("method is weird");
    }catch (IllegalStateException e){
         assertThat(e.getMessage()).isEqualTo("이미 존재하는 회원입니다.");
        }
        //then
    }

こちらの場合、ケースが少ないので、try-catch以外の方法でも処理できます。

    @Test
    void 중복_회원_예외(){
        //given
        Member member1 = new Member();
        member1.setName("spring");

        Member member2 = new Member();
        member2.setName("spring");

        //when
        memberService.join(member1);
        //() -> memberService.join(member2)を実行したらIllegalStateException classが発生する
        assertThrows(IllegalStateException.class, () -> memberService.join(member2));

        //then
    }

assertThrowsは、メッセージをリターンするので、以下のようにメッセージを代入することができます。

  @Test
    void 중복_회원_예외(){
        //given
        Member member1 = new Member();
        member1.setName("spring");

        Member member2 = new Member();
        member2.setName("spring");

        //when
        memberService.join(member1);
        //() -> memberService.join(member2)を実行したらIllegalStateException classが発生する
        IllegalStateException e = assertThrows(IllegalStateException.class, () -> memberService.join(member2));

        assertThat(e.getMessage()).isEqualTo("이미 존재하는 회원입니다.");

        //then
    }

@beforeEach

public class MemoryMemberRepository implements MemberRepository{

    private static Map<Long,Member> store = new HashMap<>();
    private static long sequence = 0L;

MemoryMemberRepositoryは、メモリ上に事前に上がっているstatic Map, static longを持っています。

しかし、MemoryMemberRepositoryが二つ、三つのオブジェクトになれば、static Map, static longをシェアする状況になります。

今、MemberServiceとMemberServiceTestクラスを見れば、

 private final MemberRepository memberRepository= new MemoryMemberRepository();
 MemberService memberService = new MemberService();
    MemoryMemberRepository memberRepository = new MemoryMemberRepository();

MemberServiceはMemberRepositoryを、MemberServiceTestはMemberServiceをnew 演算子で生成することが分かります。

今はMemberMemoryRepositoryのMap,longがstaticですので、構いませんが、MemberMemoryRepositoryのオブジェクトを二つ以上生成する必要もありません。

MemberMemoryRepositoryを一つで統合する必要があります。

そのため、まずMemberServiceからMemberMemoryRepositoryを自ら生成することを防ぎます。TESTの際にMemberServiceを新しく生成することで、MemberMemoryRepositoryも部品としてともに新しいオブジェクトが生成されるからです。

DI

このような問題を解決すためには、まずMemberServiceからMemberMemoryRepositoryを自ら生成することを防ぐ必要があります。
こういうことをDI(Dependency injection)と言います。

MemberService
 private final MemberRepository memberRepository;

    public MemberService(MemberRepository memberRepository) {
        this.memberRepository = memberRepository;
    }
MemberServiceTest
   MemberService memberService;
   MemoryMemberRepository memberRepository;

   @BeforeEach
   public void beforeEach(){
       memberRepository = new MemoryMemberRepository();
       memberService = new MemberService(memberRepository;);
   }


Discussion