Chcę utworzyć kod testowalny jednostki, który wyśmiewa połączenia z klasami .Net System.IO, więc mogę naprawdę testować jednostki zamiast zależeć od systemu plików. Używam klas SystemWrapper do owijania wokół klas BCL.Jak utworzyć testowalny kod za pomocą klas .Net IO?
Próbuję uzyskać prosty przykład pracy, aby sprawdzić, czy plik istnieje.
Problem polega na tym, że wstrzyknięcie zależności w klasie nie działa, ponieważ utworzenie instancji zależnej (przez StructureMap) wymaga znajomości parametru konstruktora, który nie będzie dostępny w tym czasie, brak domyślnego konstruktora.
przykładowy kod:
// don't want to create dependency here like so
//IFileInfoWrap fileInfoWrap = new FileInfoWrap(filename);
// using service locator (anti-pattern?!) since it can't be
// injected in this class
var fileInfoWrap = ObjectFactory.GetInstance<IFileInfoWrap>(
new ExplicitArguments(new Dictionary<string, object>
{
{"fileName", filename}
}));
Console.WriteLine("File exists? {0}", fileInfoWrap.Exists);
Co mi się nie podoba to, że zależność nie jest wstrzykiwany, ObjectFactory nie powinno tu być (ale nie widzę innego sposobu tworzenia tego). ExplicitArguments sprawia, że jest on brudny, a nazwa-argumentu jest ciągiem magicznym.
Dla mnie to do pracy klasę StructureMap config musi wiedzieć explict który konstruktor chcę użyć (I właśnie rozpoczęła z StructureMap więc to nie może być właściwym sposobem, aby ustawić go w górę):
ObjectFactory.Initialize(x =>
{
x.Scan(scan =>
{
scan.AssembliesFromPath(".");
scan.RegisterConcreteTypesAgainstTheFirstInterface();
scan.WithDefaultConventions();
});
// use the correct constructor (string instead of FileInfo)
x.SelectConstructor(() => new FileInfoWrap(null as string));
// setting the value of the constructor
x.For<IFileInfoWrap>()
.Use<FileInfoWrap>()
.Ctor<string>("fileName")
.Is(@".");
});
Czy ktoś znalazł lepsze rozwiązanie, aby utworzyć testowalny kod na klasach System.IO? Wiem, że część problemu tkwi w projektowaniu klas System.IO.
SystemWrapper zawiera przede wszystkim bardzo nieszczelne abstrakcje. Byłoby znacznie prostsze i łatwiejsze modelowanie IO przeciwko strumieniom, TextWriter, TextReader itp. Klasy te są już abstrakcyjne, całkowicie eliminując potrzebę SystemWrapper. –
Kolejny głos na strumienie –
Moje odkrycia z SystemWrapper są takie, że wydaje się być ładnym opakowaniem z interfejsami, jednak jest to ślepy zaułek ze względu na sposób działania oryginalnych klas. Na przykład zwracanie tablicy obiektów FileInfo nie może być wyśmiewane poprawnie. Przetwarzanie mojej własnej, bardziej uproszczonej owijki, która nie musi naśladować istniejących klas, podczas gdy więcej pracy prowadzi do praktycznego rozwiązania IMHO. –