Zanim zacznę, jestem wielkim fanem AutoFixture, wciąż jestem w stanie nauczyć się korzystać z tego narzędzia. Dziękuję za opracowanie Autofixture Mr Ploeh i wszystkich współpracowników.Nie mogę uchwycić różnicy między Freeze/Inject/Register
Zacznijmy od mojego pytania.
Według AutoFixture/AutoMoq ignores injected instance/frozen mock
Interesującą częścią powyższy link podany jest ten kod
Mock<ISettings> settingsMock = new Mock<ISettings>();
settingsMock.Setup(s => s.Get(settingKey)).Returns(xmlString);
ISettings settings = settingsMock.Object;
fixture.Inject(settings);
Do którego Mark odpowiedź może być przepisany do
fixture.Freeze<Mock<ISettings>>()
.Setup(s => s.Get(settingKey)).Returns(xmlString);
To wygląda jak cukier składniowy, za pomocą metody Freeze można pisać płynnie w interfejsie, tworząc makietę, konfigurację i iniekcję w pojemniku z autofixture.
Po przeprowadzeniu badań w Internecie, faktycznie istnieje różnica funkcjonalna między zamrożeniem a wstrzykiwaniem. Znalazłem to pytanie: https://github.com/AutoFixture/AutoFixture/issues/59 tym momencie odpowiedź How can I Freeze a null instance in AutoFixture
autor link powyżej opisać metodę zamrażania jak:
wewnętrznie, zamrożenie tworzy instancję żądanego typu (np IPayPalConfiguration), a następnie wstrzykuje go tak będzie zawsze wrócić tego wystąpienia, gdy poprosisz go ponownie
i under t i że gdy wykonamy
var customer = fixture.Freeze<Order>();
to zawsze użyje tego samego wystąpienia Zamówienia, gdy nasz kod zażąda typu Zamówienia. Ale co jeśli określę w konstruktorze Freeze, że chcę użyć konkretnej instancji?
Oto mały przykład kodu:
[Fact]
public void MethodeName()
{
var fixture = new Fixture().Customize(new AutoMoqCustomization());
fixture.Freeze<OrderLine>(new OrderLine("Foo"));
var order = fixture.Create<Order>();
}
public class Order
{
private readonly OrderLine _line;
public Order(OrderLine line)
{
_line = line;
}
}
public class OrderLine
{
private readonly string _name;
public OrderLine(string name)
{
_name = name;
}
}
nie powinien nazwa Orderline być równy "Foo" zamiast namefe48163a-d5a0-49a5-b349-7b11ba5f804b? Dokumentacja metody Freeze mówi:
<typeparam name="T">The type to freeze.</typeparam>
<param name="fixture">The fixture.</param>
<param name="seed">Any data that adds additional information when creating the anonymous object. Hypothetically, this value might be the value being frozen, but this is not likely.</param>
dlaczego autor nie jest pewien, kiedy zwracana jest wartość? Jeśli określę, moja instancja w konstruktorze Freeze, oczekuję, że autofixture użyje tej instancji?
następnie
Proszę zauważyć, że nie jest prawdopodobne, aby być stosowane jako wartości zamrożone, o ile nie zostaną dostosowane do tego celu. Jeśli chcesz wprowadzić konkretną wartość do Urządzenia, powinieneś użyć tej metody. "
Wygląda na to, że muszę dostosować parametr początkowy. Czy ktoś może wyjaśnić? Rozwiązaniem wskazanym w dokumentacji jest użycie metody Inject. I rzeczywiście działa w moim przykładzie kodu z OrderLine.
Poszukuję twojej pomocy w zrozumieniu różnicy między Freeze, Inject, a także Register, która zgodnie z kodem źródłowym jest wywoływana tylko metodą Inject, ale wymaga lambda.
btw. jedną z przyczyn, dla których to przeciążenie wciąż się znajduje, może być fakt, że ReSharper wydaje się być ustawiony tak, aby domyślnie ignorował atrybut 'EditorBrowsable'. – TeaDrivenDev
FWIW, w AutoFixture, planuję przenieść (lub zabrać) przeciążenia nasion od: https://github.com/AutoFixture/AutoFixture/issues/151 –