ho incontrato una classe durante il mio lavoro che assomiglia a questo:Creazione di un ibrido di un oggetto di simulazione e anonimo utilizzando ad es. Moq e AutoFixture?
public class MyObject
{
public int? A {get; set;}
public int? B {get; set;}
public int? C {get; set;}
public virtual int? GetSomeValue()
{
//simplified behavior:
return A ?? B ?? C;
}
}
Il problema è che ho un po 'di codice che accede A, B e C e chiama il metodo GetSomeValue() (ora, direi questo non è un buon design, ma a volte le mie mani sono legate ;-)). Voglio creare una simulazione di questo oggetto, che, allo stesso tempo, ha A, B e C impostati su alcuni valori. Così, quando uso moq come tale:
var m = new Mock<MyObject>() { DefaultValue = DefaultValue.Mock };
mi permette di impostare un risultato su GetSomeValue() metodo, ma tutte le proprietà sono impostate su null (e la creazione di tutti loro con il programma di installazione() è abbastanza ingombrante, poiché l'oggetto reale è un brutto oggetto dati e ha più proprietà rispetto all'esempio semplificato sopra).
Così d'altra parte, utilizzando AutoFixture come questo:
var fixture = new Fixture();
var anyMyObject = fixture.CreateAnonymous<MyObject>();
mi lascia senza la capacità di Stup una chiamata al metodo GetSomeValue().
C'è un modo per combinare i due, per avere valori anonimi e la possibilità di impostare i risultati delle chiamate?
Modifica
in base alla risposta del nemesv, ho derivato il seguente metodo di utilità (spero capito bene):
public static Mock<T> AnonymousMock<T>() where T : class
{
var mock = new Mock<T>();
fixture.Customize<T>(c => c.FromFactory(() => mock.Object));
fixture.CreateAnonymous<T>();
fixture.Customizations.RemoveAt(0);
return mock;
}
Questa è una bella soluzione, soprattutto perché copre tipi nidificati, tuttavia, per essere più generale, con i tipi nidificati, c'è qualche modo per sbarazzarsi della parte: t == typeof (MyObject) | | t == typeof (MyParent)? La logica che sto pensando è qualcosa del tipo: "se il tipo annidato dell'ibrido è mockable, rendilo un ibrido, altrimenti rendilo un valore anonimo". –
Sì, basta sostituire il predicato con qualcosa di più generale. –
Grazie! Ho provato ad usare un predicato di (t! = Null &&! T.IsPrimitive && (t.GetConstructors (BindingFlags.Public) .Length! = 0 || t.GetConstructor (Type.EmptyTypes)! = Null)) e sembra lavorare! Riesci a vedere qualcosa che manca qui? Proverò a provarlo un po 'e cercherò di farti sapere se qualcosa viene fuori. –