Autofixture: 4.0.0-rc1์—์„œ ๊ธฐ๋ณธ ํด๋ž˜์Šค ๋˜๋Š” ์ธํ„ฐํŽ˜์ด์Šค์˜ ์‚ฌ์šฉ์ž ์ •์˜ ์ ์šฉ ์‹คํŒจ(ํšŒ๊ท€)

์— ๋งŒ๋“  2017๋…„ 11์›” 20์ผ  ยท  10์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: AutoFixture/AutoFixture

๋‹ค์Œ ํ…Œ์ŠคํŠธ๋Š” AutoFixture 3.51.0 ์—์„œ ์„ฑ๊ณตํ•˜์ง€๋งŒ 4.0.0-rc1 ์—์„œ ์‹คํŒจํ•ฉ๋‹ˆ๋‹ค.
(๋งˆ์Šคํ„ฐ์˜ ์ตœ์‹  ์ปค๋ฐ‹์—์„œ๋„: c856cd6 )

``` C#
[์‚ฌ์‹ค]
๊ณต๊ฐœ ๋ฌดํšจ ShouldApplyCustomizationsFromBaseClass()
{
var ๊ณ ์ • ์žฅ์น˜ = new Fixture();
์ •์ฐฉ๋ฌผ.์‚ฌ์šฉ์ž ์ •์˜(c => c.Without(bc => bc.Id));
var res = fixture.Create();
Assert.Equal(0, res.Id);
}

[์‚ฌ์‹ค]
๊ณต๊ฐœ ๋ฌดํšจ ShouldApplyCustomizationsFromInterface()
{
var ๊ณ ์ • ์žฅ์น˜ = new Fixture();
์ •์ฐฉ๋ฌผ.์‚ฌ์šฉ์ž ์ •์˜(c => c.Without(bc => bc.Id));
var res = fixture.Create();
Assert.Equal(0, res.Id);
}

๊ณต๊ฐœ ์ธํ„ฐํŽ˜์ด์Šค IInterface
{
์ •์ˆ˜ ID { ๊ฐ€์ ธ์˜ค๊ธฐ; ์„ธํŠธ; }
}

๊ณต๊ฐœ ํด๋ž˜์Šค
{
๊ณต๊ฐœ ์ •์ˆ˜ ID { ๊ฐ€์ ธ์˜ค๊ธฐ; ์„ธํŠธ; }
}

๊ณต์šฉ ํด๋ž˜์Šค ImplClass : BaseClass, IInterface
{

}
```

question

๋ชจ๋“  10 ๋Œ“๊ธ€

์งˆ๋ฌธ์„ ์˜ฌ๋ ค์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ๊ธ€์Ž„, ์ด๊ฒƒ์€ ์›ํ•˜๋Š” ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด๋ฉฐ ์˜๋„์ ์œผ๋กœ ์ ์šฉ๋œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ด์ „์—๋Š” ํ•œ ํ•˜์œ„ ์œ ํ˜•์˜ ์‚ฌ์šฉ์ž ์ง€์ •์ด ๋‹ค๋ฅธ ํ•˜์œ„ ์œ ํ˜•์— ์˜ํ–ฅ์„ ์ค„ ์ˆ˜ ์žˆ๋Š” ๋ฌธ์ œ๊ฐ€ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด:

```c#
ํด๋ž˜์Šค ๊ธฐ๋ณธ { ๊ณต๊ฐœ ๋ฌธ์ž์—ด ๊ณตํ†ต { get; ์„ธํŠธ; } }
ํด๋ž˜์Šค Child1: ๊ธฐ๋ณธ { }
ํด๋ž˜์Šค Child2: ๊ธฐ๋ณธ { }

[์‚ฌ์‹ค]
๊ณต๊ฐœ ๋ฌดํšจ ๋ณด์žฅCustomizationAreNotAffected()
{
var ๊ณ ์ • ์žฅ์น˜ = new Fixture();
์ •์ฐฉ๋ฌผ.์‚ฌ์šฉ์ž ์ •์˜(c => c.With(x => x.Common, "๋”๋ฏธ"));

var result = fixture.Create<Child2>();

Assert.NotNull(result.Common);

}


In the v3 this test failed, causing a lot of confusion to people. As you might imagine, the scenarios were more complicated and it was very non-obvious why the particular members are not initialized. 

For instance, the following code will not work, which again proves that API is not designed for that.
```c#
fixture.Customize<Base>(c => c.With(x => x.Common, "foo"));

๋”ฐ๋ผ์„œ ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ์ ‘๊ทผ ๋ฐฉ์‹์„ ๋ณ€๊ฒฝํ•˜์—ฌ ์ด์ œ ํ•œ ์œ ํ˜•์˜ ์‚ฌ์šฉ์ž ์ •์˜๊ฐ€ ๋™์ผํ•œ ์ƒ์† ๋ผ์ธ์— ์†ํ•˜๋”๋ผ๋„ ๋‹ค๋ฅธ ์œ ํ˜•์— ์˜ํ–ฅ์„ ์ค„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค . ํ•ด๋‹น PR์—์„œ ๋ณผ ์ˆ˜ ์žˆ๋“ฏ์ด ๋งŽ์€ ์‚ฌ์šฉ์„ฑ ๋ฌธ์ œ๋ฅผ ์ˆ˜์ •ํ•˜๊ณ  ๋” ๋ช…ํ™•์„ฑ์„ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค(๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ์‹ค์ œ๋กœ ์ค‘๋‹จ๋˜๋Š” ๋™์•ˆ).

๊ทธ๋ž˜๋„ ๊ธฐ๋ณธ/์ธํ„ฐํŽ˜์ด์Šค ์†์„ฑ์„ ์ƒ๋žตํ•˜๋ ค๋ฉด ๋‹ค์Œ ์Šค๋‹ˆํŽซ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
```c#
๊ฐœ์ธ ํด๋ž˜์Šค SamePropertySpecification : IRequestSpecification
{
๊ฐœ์ธ ์ฝ๊ธฐ ์ „์šฉ ์œ ํ˜• _declaringType;
๊ฐœ์ธ ์ฝ๊ธฐ ์ „์šฉ ๋ฌธ์ž์—ด _name;

public SamePropertySpecification(Type declaringType, string name)
{
    _declaringType = declaringType;
    _name = name;
}

public bool IsSatisfiedBy(object request)
{
    if (request is PropertyInfo pi)
    {
        return pi.DeclaringType == this._declaringType &&
               pi.Name.Equals(this._name, StringComparison.Ordinal);
    }

    return false;
}

}

[์‚ฌ์‹ค]
๊ณต๊ฐœ ๋ฌดํšจ TestBasePropertyOmitting()
{
var ๊ณ ์ • ์žฅ์น˜ = new Fixture();

fixture.Customizations.Add(new Omitter(new SamePropertySpecification(typeof(Base), nameof(Base.Common))));

var result = fixture.Create<Child1>();
Assert.Null(result.Common);

}
```

ํ•ด๋‹น ๊ธฐ๋Šฅ์ด ์ž์ฃผ ํ•„์š”ํ•œ ๊ฒฝ์šฐ fixture ๋Œ€ํ•œ ๊ณ ์œ ํ•œ ํ™•์žฅ ๋ฐฉ๋ฒ•์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋‚˜๋Š” ๋งค์šฐ ํ˜ผ๋ž€์Šค๋Ÿฌ์›Œ ๋ณด์ด๊ธฐ ๋•Œ๋ฌธ์— ๊ทธ๋Ÿฌํ•œ ๊ธฐ๋Šฅ์„ ์ฆ‰์‹œ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์— ํˆฌํ‘œํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

์•Œ๊ฒ ์Šต๋‹ˆ๋‹ค. ์˜๋„์ ์ด์—ˆ์Šต๋‹ˆ๋‹ค. ํ˜ผ๋ž€์Šค๋Ÿฝ๋‹ค๋Š” ์ ์—๋Š” ํ™•์‹คํžˆ ๋™์˜ํ•˜์ง€๋งŒ ๋ช…์‹œ์ ์œผ๋กœ ์ ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด ์ข‹์€ ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค. ์Šค ๋‹ˆํŽซ์„ ์‹œ๋„ํ•˜๊ณ  ์•„๋งˆ๋„ ํ™•์žฅ ๋ฐฉ๋ฒ•์„ ๋งŒ๋“ค ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๊ทธ๊ฑด ๊ทธ๋ ‡๊ณ : ์ด๊ฒƒ์ด ์ฃผ์š” ๋ณ€๊ฒฝ ์‚ฌํ•ญ ๋ชฉ๋ก์— ์ถ”๊ฐ€ํ•˜๊ณ  ์‹ถ์€ ๊ฒƒ์ž…๋‹ˆ๊นŒ? ๊ฐ™์€ ์งˆ๋ฌธ์ด ๋ฐ˜๋ณต๋˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ชจ๋“  ์‚ฌ์šฉ์ž ์ •์˜ ์ค‘ ํ•˜๋‚˜์˜ ์‚ฌ์šฉ์ž ์ •์˜์— ๋Œ€ํ•ด ์ด์ „ ๋™์ž‘์„ ์„ ํƒํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ์—†์Šต๋‹ˆ๋‹ค. ๋งž์Šต๋‹ˆ๊นŒ?

์ด๊ฒƒ์ด ์ฃผ์š” ๋ณ€๊ฒฝ ์‚ฌํ•ญ ๋ชฉ๋ก์— ์ถ”๊ฐ€ํ•˜๊ณ  ์‹ถ์€ ๊ฒƒ์ž…๋‹ˆ๊นŒ?

๊ธ€์Ž„, ๊ทธ๊ฒƒ์€ ๋ฒ„๊ทธ ์ˆ˜์ • ์„น์…˜์— ์–ธ๊ธ‰๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ์ด์ „ ๋™์ž‘์ด "๊ธฐ๋Šฅ"์œผ๋กœ ์–ธ๊ธ‰๋œ ์ ์ด ์—†๊ธฐ ๋•Œ๋ฌธ์— ์‹ค์ œ๋กœ๋Š” ์ฃผ์š” ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ์•„๋‹™๋‹ˆ๋‹ค. ์˜คํžˆ๋ ค, ๊ทธ๊ฒƒ์€ ๋ฐ”๋žŒ์งํ•˜์ง€ ์•Š์€ ๋ถ€์ž‘์šฉ์ด์—ˆ๊ณ  ๋งˆ์นจ๋‚ด ์ œ๊ฑฐ๋˜์—ˆ์Šต๋‹ˆ๋‹ค ๐Ÿ˜‰

๋ชจ๋“  ์‚ฌ์šฉ์ž ์ •์˜ ์ค‘ ํ•˜๋‚˜์˜ ์‚ฌ์šฉ์ž ์ •์˜์— ๋Œ€ํ•ด ์ด์ „ ๋™์ž‘์„ ์„ ํƒํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ์—†์Šต๋‹ˆ๋‹ค. ๋งž์Šต๋‹ˆ๊นŒ?

์•„๋‹ˆ์š”, ์ ‘๊ทผ ๋ฐฉ์‹์„ ์™„์ „ํžˆ ์žฌ์ž‘์—…ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ฏฟ์„ ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์€ ์—†์Šต๋‹ˆ๋‹ค.

์Šค๋‹ˆํŽซ์„ ํ…Œ์ŠคํŠธํ•˜๊ณ  ์ž‘๋™ํ•˜๋Š” ๊ฒฝ์šฐ ๋ฌธ์ œ๋ฅผ ์ข…๋ฃŒํ•˜์‹ญ์‹œ์˜ค. ๋˜๋Š” ์ถ”๊ฐ€ ์งˆ๋ฌธ์ด ์žˆ์œผ๋ฉด ์•Œ๋ ค์ฃผ์„ธ์š” ๐Ÿ˜ƒ

์ธํ„ฐํŽ˜์ด์Šค์—์„œ๋„ ์ž‘๋™ํ•˜๋„๋ก ์ˆ˜์ •ํ–ˆ๊ณ  'Fixture.Customize์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ™•์žฅ ๋ฉ”์„œ๋“œ๋ฅผ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค.(...)'. ํŠนํžˆ v3์—์„œ ์ž‘๋™ํ•˜๋Š” ๋ฐฉ์‹์ด ์šฐ๋ฆฌ์—๊ฒŒ ์™„๋ฒฝํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ๋‚ด๊ฐ€ ์›ํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ์•ฝ๊ฐ„ ๋” ํ•ดํ‚น๋œ ๋Š๋‚Œ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์šฐ๋ฆฌ์˜ ์œ ์ผํ•œ ์œ ์Šค ์ผ€์ด์Šค๋Š” ์†์„ฑ์„ ์ƒ๋žตํ•˜๊ณ  (๊ฐ€์žฅ ์ค‘์š”ํ•˜๊ฒŒ๋Š” ๐Ÿ˜‰ ) ์ž‘๋™ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ํŠธ๋ฆญ์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. ๊ฐ์‚ฌ ํ•ด์š”!

@nphmuller ์ œ๊ฐ€ ๋‹น์‹ ์˜ ๊น”๋”ํ•˜๊ณ  ๊น”๋”ํ•œ ์ฝ”๋“œ๋ฅผ

์ „ํ˜€ ๋น„๋‚œํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋‹น์‹ ์˜ ์ถ”๋ก ์„ ์™„๋ฒฝํ•˜๊ฒŒ ์ดํ•ดํ•˜๊ณ  ๋™์˜ํ•˜์‹ญ์‹œ์˜ค. ์ €์—๊ฒŒ๋Š” ๊ทธ๋ƒฅ ์ž…๋‹ˆ๋‹ค ๐Ÿ˜‰

๋” ๊น”๋”ํ•œ ๋ฐฉ๋ฒ•์ด ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด ๋‚˜์ค‘์— ๋ฌธ์ œ์— ๋›ฐ์–ด๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ง€๊ธˆ์€ ๊ดœ์ฐฎ์Šต๋‹ˆ๋‹ค.

๊ทธ๋ƒฅ ํ˜ธ๊ธฐ์‹ฌ์—์„œ - ์‹ค์ œ ์‚ฌ์šฉ ์‚ฌ๋ก€๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ? ๊ทธ๋Ÿฐ ์ข…๋ฅ˜์˜ ๊ธฐ๋Šฅ์— ๋Œ€ํ•œ ์š”๊ตฌ๋ฅผ ์ถฉ์กฑํ•œ ์ ์ด ์—†๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ ํ…Œ์ŠคํŠธ๋ฅผ ์ž‘์„ฑํ•  ๋•Œ ๊ธฐ๋ณธ ๋˜๋Š” ์ธํ„ฐํŽ˜์ด์Šค ์œ ํ˜•์„ ๊ตฌ์„ฑํ•˜์ง€ ์•Š๊ณ  ํŠน์ • ์œ ํ˜•๋งŒ ์‚ฌ์šฉ์ž ์ •์˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ผ์ข…์˜ ๊ธ€๋กœ๋ฒŒ ์‚ฌ์šฉ์ž ์ •์˜๋ฅผ ์ž‘์„ฑํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๊นŒ?

์ด ๊ฒฝ์šฐ AutoFixture๋ฅผ Entity Framework ํ†ตํ•ฉ ํ…Œ์ŠคํŠธ๋ฅผ ์œ„ํ•œ ํ…Œ์ŠคํŠธ ๋ฐ์ดํ„ฐ ์ƒ์„ฑ๊ธฐ๋กœ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

๊ณตํ†ต ์†์„ฑ์„ ํฌํ•จํ•˜๋Š” ์—”ํ„ฐํ‹ฐ๊ฐ€ ์‚ฌ์šฉํ•˜๋Š” ๋ช‡ ๊ฐ€์ง€ ๊ธฐ๋ณธ ์œ ํ˜• ๋˜๋Š” ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ID, ํ…Œ๋„ŒํŠธ ID(๋ฐ ํƒ์ƒ‰ ์†์„ฑ), ์ด์™€ ๊ฐ™์€ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด ์ด๋Ÿฌํ•œ ์†์„ฑ ์ค‘ ํ•˜๋‚˜๋Š” ๊ฐœ์ฒด๋ฅผ ๋งŒ๋“  ์‚ฌ์šฉ์ž์ž…๋‹ˆ๋‹ค. ์ด ์†์„ฑ์€ ๋Œ€๋ถ€๋ถ„์˜ ํ…Œ์ŠคํŠธ์—์„œ ๊ทธ๋‹ค์ง€ ํฅ๋ฏธ๋กญ์ง€ ์•Š์œผ๋ฉฐ ์ƒ์„ฑ๋œ ๊ฒฝ์šฐ ์ƒ์„ฑ๋˜์–ด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์‚ฝ์ž…๋˜์–ด์•ผ ํ•˜๋Š” ๊ฑฐ๋Œ€ํ•œ ๊ทธ๋ž˜ํ”„(User ํด๋ž˜์Šค์—๋„ ๋งŽ์€ ํƒ์ƒ‰ ์†์„ฑ์ด ์žˆ์Œ)๊ฐ€ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๊ฐœ์ฒด๊ฐ€ ๊ทธ๋Ÿฐ ์‹์œผ๋กœ ์‚ฝ์ž…๋˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— ํ…Œ์ŠคํŠธ๊ฐ€ ๋Š๋ ค์ง€๊ฑฐ๋‚˜ db ์ˆ˜์ค€์—์„œ ์‹คํŒจํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ ์ด๋Ÿฌํ•œ ์†์„ฑ์„ ์ œ์™ธํ•˜๊ณ  ํ•„์š”ํ•  ๋•Œ ์„ ํƒํ•˜๋Š” ๊ฒƒ์ด ๋” ์‰ฝ์Šต๋‹ˆ๋‹ค. ๊ธฐ๋ณธ ํด๋ž˜์Šค ์ˆ˜์ค€์—์„œ ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ๋ชจ๋“  ์—”ํ„ฐํ‹ฐ ์œ ํ˜•์— ๋Œ€ํ•ด ๋™์ผํ•œ ์ƒ๋žต ๊ทœ์น™์„ ์ž‘์„ฑํ•ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

@nphmuller ์„ค๋ช…

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰

๊ด€๋ จ ๋ฌธ์ œ

malylemire1 picture malylemire1  ยท  7์ฝ”๋ฉ˜ํŠธ

josh-degraw picture josh-degraw  ยท  4์ฝ”๋ฉ˜ํŠธ

zvirja picture zvirja  ยท  3์ฝ”๋ฉ˜ํŠธ

ploeh picture ploeh  ยท  3์ฝ”๋ฉ˜ํŠธ

mjfreelancing picture mjfreelancing  ยท  4์ฝ”๋ฉ˜ํŠธ