#268์์ ๋
ผ์๋ ๋ฐ์ ๊ฐ์ด GuardClauseAssertion
ํด๋์ค๋ ์์
์ด ์๋ฃ๋ ๋๊น์ง ๊ธฐ๋ค๋ฆฌ์ง ์์ผ๋ฏ๋ก non- fail fast ๋ฉ์๋๋ฅผ ๊ฒ์ฆํ ์ ์์ต๋๋ค.
๋น ๋ฅธ ํ์ผ(fail fast) ์ด ์ค์ ๋ก ์ต์ ์ ์ ํ์ด๊ธฐ ๋๋ฌธ์ ์ด๊ฒ์ ์์ ํ ์ดํดํ async
ํค์๋๋ก ํ์๋ ๋ฉ์๋๋ฅผ ์ฒ๋ฆฌํ ๋ ๋น ๋ฅธ ์คํจ ๋์์ ๊ตฌํํ๋ ๊ฒ์ ๋ถ๊ฐ๋ฅํด ๋ณด์
๋๋ค.
async
ํค์๋๋ก ํ์๋ ๋ฉ์๋๋ฅผ ๋ค๋ฃฐ ๋ _fail fast_ ๋์์ ๊ตฌํํ๋ ๊ฒ์ ๋ถ๊ฐ๋ฅํด ๋ณด์ ๋๋ค.
์ด๋์? ์๋ฅผ ๋ค์ด ์ค ์ ์์ต๋๊น?
@ploeh ๊ธฐ๋ณธ์ ์ผ๋ก _any_ async
๋ฉ์๋๋ ์คํจํ์ง ์์ต๋๋ค. ๋ค์ ์๋ฅผ ๊ณ ๋ คํ์ญ์์ค.
```c#
๊ณต๊ฐ ๋น๋๊ธฐ ์์
{
if (arg == null) throw new ArgumentNullException(nameof(arg));
await Task.Yield();
return default;
}
```
์ด ๋ฉ์๋๋ ํธ์ถํ๋ฉด ๋์ง์ง ์์ต๋๋ค. null
๋ฉ๋๋ค. ๋์ ์คํจํ Task
๊ฐ ๋ฐํ๋ฉ๋๋ค. ๋ฐ๋ผ์ ํ์ฌ ํ์์ GuardClauseAssertion์ ์คํจํ๊ณ ๊ฐ๋ ์ ๋๋ฝ์ ๋ํด ๋ถํํฉ๋๋ค.
์ค์ ์ ํ๋ฆฌ์ผ์ด์
์์ ๊ฑฐ์ ๋ชจ๋ ์ฝ๋๋ async
์ด๋ฏ๋ก ๊ฐ ํธ์ถ์ awaited
์ด๊ณ ์์ธ๋ ์ฆ์ ๋ฐ์ํฉ๋๋ค. ๋ฐ๋ผ์ ์์ธ๋ฅผ ๋ณด๋ ค๋ฉด await
Task๋ฅผ ์ํํด์ผ ํ๋ ํ์์์ "๋น ๋ฅธ ์คํจ" ์์น์ ์๋ฐํ๋ ๊ฒ์ ์์ ํ ๊ด์ฐฎ์ต๋๋ค.
๋ฌผ๋ก ์ฝ๋๋ฅผ ๋ค์ ์์ฑํ์ฌ ์ฆ์ ์คํจํ๋๋ก ํ ์ ์์ง๋ง( async
ํค์๋๋ก private ํจ์๋ฅผ ๋ง๋ค๊ณ ๋ชจ๋ ๋
ผ๋ฆฌ๋ฅผ ๊ฑฐ๊ธฐ๋ก ์ด๋) ๊ทธ๋ ๊ฒ ํ๋ ๊ฒ์ ์ค์ฉ์ ์ด์ง ์์ต๋๋ค.
์ค์ ์์ฉ ํ๋ก๊ทธ๋จ์์ ๊ฑฐ์ ๋ชจ๋ ์ฝ๋๋
async
์ด๋ฏ๋ก ๊ฐ ํธ์ถ์awaited
์ด๊ณ ์์ธ๋ ์ฆ์ ๋ฐ์ํฉ๋๋ค.
๊ทธ๊ฒ์ ์ ๋นํ ์ง์ ์ ๋๋ค. ๋๋ ๊ทธ ์ฃผ์ฅ์ ๋ฐ์๋ค์ธ๋ค.
๋๋ ๋๊ตฐ๊ฐ๊ฐ (๊ฑฐ์ ์ฆ๊ฑฐ ์์ด) ๋ฌด์ธ๊ฐ๊ฐ _๋ถ๊ฐ๋ฅ_ํ๋ค๊ณ ์ฃผ์ฅํ๊ฑฐ๋ ์์ํ ๋ ๋๋๋ก ๊ธธ์ ์์ต๋๋ค...
๋๊ตฐ๊ฐ๊ฐ ๋ฌด์ธ๊ฐ๊ฐ ๋ถ๊ฐ๋ฅํ๋ค๊ณ ์ฃผ์ฅํ๊ฑฐ๋ ์์ํ ๋ (์ฆ๊ฑฐ๊ฐ ๊ฑฐ์ ์์) ๋๋๋ก ๊ธธ์ ์์ต๋๋ค...
์, ์ถฉ๋ถํ ๊ณตํํฉ๋๋ค ๐
์ด์ ๋ถ์ธ ํ๋๊ทธ๋ฅผ ์ฌ์ฉํ์ง ์๋๋ก GuardClauseAssertion
๋ฅผ ๋ค์ ๋์์ธํ๋ ๋ฐฉ๋ฒ์ ์๊ฐํด ๋ณด๊ฒ ์ต๋๋ค. ๋์ค์ PR์์ ๋ต๊ฒ ์ต๋๋ค.
์ด์ ๋ถ์ธ ํ๋๊ทธ๊ฐ ์๋๋ก
GuardClauseAssertion
๋ฅผ ๋ค์ ๋์์ธํ๋ ๋ฐฉ๋ฒ์ ์๊ฐํด ๋ณด๊ฒ ์ต๋๋ค.
@moodmosaic์ด ์ ์ํ ๊ฒ์ฒ๋ผ ์ ํด๋์ค๊ฐ ๋ ๋์ ๋์์ธ์ผ ์ ์๋ค๊ณ ์๊ฐํฉ๋๋ค. ๋ฌธ์ ๋ฅผ ์์ธํ ์ดํด๋ณด์ง๋ ์์์ง๋ง ํ๋ฆด ์ ์๋ ๊ถ๋ฆฌ๊ฐ ์์ต๋๋ค ๐
๋ค์์ ๋ด๊ฐ ์ฌ์ฉํ ์๋ฃจ์ ์ ๋๋ค.
async
ํค์๋ ์ ๊ฑฐasync
ํค์๋๋ฅผ ์ฌ์ฉํ์ฌ ์ค์ฒฉ ๋ฉ์๋ ๋ง๋ค๊ธฐ์์:
public Task<int> GetNumberAsync(MyObject obj)
{
// Fail-fast behavior
if (request is null)
throw new ArgumentNullException(nameof(obj));
async Task<int> work()
{
var items = await obj.GetItemsAsync(); // whatever you need to call
return items.Count();
}
return work();
}
๊ทธ๊ฒ์ ์ ์๊ฒ ์ข์ ํด๊ฒฐ์ฑ ์ด ๋์์ต๋๋ค. ๋น์ ์ ๋์์ ์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค.
@mniak @zvirja ๊ฐ ์ฌ๊ธฐ์์ ์ ์ํ ๊ฒ์ ๋ํ ๊ตฌ์ฒด์ ์ธ ์๊ฐ ํฅ๋ฏธ ๋กญ์ต๋๋ค .
๊ฐ์ธ์ ์ผ๋ก ํ ์คํธ ํ๋ ์์ํฌ์ ์ด์ ์ ์ํด "์์์"๋ก ๋ฉ์๋๋ฅผ ์ค์ผ์ํค๊ธฐ ๋๋ฌธ์ ์ด ๋ฐฉ์์ด ๋ง์์ ๋ค์ง ์์ต๋๋ค.
๊ธฐ๋ณธ ๋ฐฉ์์ผ๋ก ์ง์์ ๊ตฌํํ๋ ค๋ฉด ์ด์ด ๋์ญ์์ค. ์ด๋ ๋ . ๊ฐ๊น์ด ๋ฏธ๋์. ์๋๋ฉด ๋จ ํ๋ฃจ.
์๋
ํ์ธ์. ์ฐ๋ฆฌ๋ ์ ํํ ์ด ๋ฌธ์ ๋ฅผ ์ฐ์ฐํ ๋ฐ๊ฒฌํ๊ณ ํ์ฌ๊น์ง ์ข์ ํด๊ฒฐ์ฑ
์ด ์๋ค๋ ์ฌ์ค์ ๋๋์ต๋๋ค.
์ด๋ฅผ ์ํด ์ ํด๋์ค๋ฅผ ๊ตฌํํ์ง ์์ ์ด์ ๊ฐ ์์ต๋๊น?
AutoFixture์ ๋ด๋ถ ์ธ๋ถ ์ฌํญ์ ๋ชจ๋ฅด์ง๋ง Method-to-Test์ ๋ํ GuardClauseAssertion ํด๋์ค ๋ด์์ MethodInfo๋ฅผ ์ฌ์ฉํ ์ ์๋ ๊ฒฝ์ฐ CustomAttributes๋ฅผ ์ดํด๋ณด๊ณ ์ด๊ฒ์ด ๋น๋๊ธฐ ๋ฉ์๋์ธ์ง ์ฌ๋ถ๋ฅผ ์๋ณํ ์ ์์ต๋๋ค(https:/ /stackoverflow.com/a/20350646). ๊ทธ๋์ ์๋ง๋ ์ค์์น(bool vs. new class)๊ฐ ํ์ํ์ง ์์ ์๋ ์์ต๋๋ค.
@zvirja @aivascu ์ด๊ฒ์ ์ฌ๊ณ ํ ์ ์์ต๋๊น? 2021๋ ์ ๋น๋๊ธฐ ๋ฉ์๋๋ฅผ ์ ๋๋ก ํ ์คํธํ ์ ์๋ ์ด์ ๋ฅผ ์ ๋ง ๋ชจ๋ฅด๊ฒ ์ต๋๋ค.
@Kralizek ์ํฉ์ ์ ๋๋ก ์ฝ์๋ค๋ฉด ์์ฒญ์ด ๊ฑฐ๋ถ๋์ง ์์๊ณ , ์ฌ์ง์ด ๊ทธ๊ฒ์ ์์ ํ๋ PR๋ ์์ต๋๋ค.
๋๋ PR์ ๊ฐ๋ตํ๊ฒ ์ดํด๋ณด์๊ณ ๋ฐ์ ํผ๋๋ฐฑ์ ๋์ํ๋ค๊ณ ๋งํด์ผ ํฉ๋๋ค.
๋ฐ๋ผ์ ๋จ์ ๊ฒ์ ํผ๋๋ฐฑ์ ๊ตฌํํ๊ฑฐ๋ ๊ตฌํ๋ ํผ๋๋ฐฑ๊ณผ ํจ๊ป ์ PR์ ์ ์ถํ๋ ๊ฒ๋ฟ์
๋๋ค.
๋ชจ๋ฐ์ผ ์ฑ์์ ๋งํฌ๋ PR์ด ์๋ณด์ฌ์ ๐
๊ฐ์ฅ ์ ์ฉํ ๋๊ธ
@ploeh ๊ธฐ๋ณธ์ ์ผ๋ก _any_
async
๋ฉ์๋๋ ์คํจํ์ง ์์ต๋๋ค. ๋ค์ ์๋ฅผ ๊ณ ๋ คํ์ญ์์ค.```c#GuardedOpenGenericMethodReturningTaskResult(๊ฐ์ฒด ์ธ์)
๊ณต๊ฐ ๋น๋๊ธฐ ์์
{
if (arg == null) throw new ArgumentNullException(nameof(arg));
}
```
์ด ๋ฉ์๋๋ ํธ์ถํ๋ฉด ๋์ง์ง ์์ต๋๋ค.
null
๋ฉ๋๋ค. ๋์ ์คํจํTask
๊ฐ ๋ฐํ๋ฉ๋๋ค. ๋ฐ๋ผ์ ํ์ฌ ํ์์ GuardClauseAssertion์ ์คํจํ๊ณ ๊ฐ๋ ์ ๋๋ฝ์ ๋ํด ๋ถํํฉ๋๋ค.์ค์ ์ ํ๋ฆฌ์ผ์ด์ ์์ ๊ฑฐ์ ๋ชจ๋ ์ฝ๋๋
async
์ด๋ฏ๋ก ๊ฐ ํธ์ถ์awaited
์ด๊ณ ์์ธ๋ ์ฆ์ ๋ฐ์ํฉ๋๋ค. ๋ฐ๋ผ์ ์์ธ๋ฅผ ๋ณด๋ ค๋ฉดawait
Task๋ฅผ ์ํํด์ผ ํ๋ ํ์์์ "๋น ๋ฅธ ์คํจ" ์์น์ ์๋ฐํ๋ ๊ฒ์ ์์ ํ ๊ด์ฐฎ์ต๋๋ค.๋ฌผ๋ก ์ฝ๋๋ฅผ ๋ค์ ์์ฑํ์ฌ ์ฆ์ ์คํจํ๋๋ก ํ ์ ์์ง๋ง(
async
ํค์๋๋ก private ํจ์๋ฅผ ๋ง๋ค๊ณ ๋ชจ๋ ๋ ผ๋ฆฌ๋ฅผ ๊ฑฐ๊ธฐ๋ก ์ด๋) ๊ทธ๋ ๊ฒ ํ๋ ๊ฒ์ ์ค์ฉ์ ์ด์ง ์์ต๋๋ค.