Ich denke, es gibt ein paar Optionen hier.
Zuerst können wir das Problem überspringen und die Abfrage separat vom Repository-Aufruf testen. Zum Beispiel könnte die getestete Klasse eine ExternalIdQuery(string id)
offen legen und wir stellen sicher, dass sie Merchant
genau dann entspricht, wenn die ExternalId
übereinstimmt. Überprüfen Sie anschließend, ob das Repository einen Anruf an GetBy
erhalten hat. Dies testet nicht den gesamten Prozess (garantiert nicht, dass wir die richtige Abfrage verwendet haben), aber es könnte ausreichend sein, besonders wenn wir Tests auf höherer Ebene haben. (In der Tat wäre ich versucht, stattdessen einen Test gegen ein In-Memory-Repo oder etwas hier zu verwenden. Der Test, so wie er geschrieben wurde, gibt uns nicht viel Sicherheit, dass das System wie erwartet funktioniert).
Wenn wir uns jedoch an den aktuellen Ansatz halten wollen, können wir entweder überprüfen, ob der Ausdrucksbaum korrekt ist (yuck), oder überprüfen, ob der an die Funktion übergebene Ausdruck wie erwartet funktioniert (etwas weniger yuck?).
[Test]
public void TestLookup()
{
var repo = Substitute.For<IRepo>();
var sut = new Sut (repo);
sut.GetByExtId ("123");
repo.Received (1).GetBy (Arg.Is<Expression<Func<Merchant, bool>>> (x => ComparesMerchantId (x)));
}
bool ComparesMerchantId (Expression<Func<Merchant, bool>> x)
{
// Option 1: inspect expression tree and make sure it matches what you want.
// Option 2: run the expression and check it behaves as you expect.
var f = x.Compile();
return f (new Merchant { ExternalId = "123" }) && !f (new Merchant { ExternalId = "999" });
}
Ein anderer Weg, dies zu tun, ist die Abfrage im GetBy
Aufruf verwendet zu erfassen und dann Standard Behauptungen, es zu überprüfen zu verwenden:
[Test]
public void TestLookup2()
{
var repo = Substitute.For<IRepo>();
var sut = new Sut (repo);
Func<Merchant, bool> query = x => false;
repo.GetBy (Arg.Do<Expression<Func<Merchant, bool>>> (x => query = x.Compile()));
sut.GetByExtId ("123");
Assert.IsTrue(query (new Merchant { ExternalId = "123" }));
Assert.IsFalse(query (new Merchant { ExternalId = "123zxcv" }));
}
Hoffnung, das hilft.