2016-05-02 7 views
2

Ich habe einen sehr seltsamen Test, den ich schreibe, testet, wenn eine E-Mail gesendet wird. Wir verwenden Hangfire, also habe ich einen Wrapper IHangfireWrapper, damit ich die Enqueue-Methode verspotten kann. Diese Enqueue-Methode benötigt einen Parameter (Expression<Action<T>>).Wie bekomme ich Werte aus einem Ausdruck? <Action<T>>?

Also wenn ich diese Methode verwenden wollte, würde es in etwa so aussehen.

_ServiceProvider.HangfireWrapper 
    .Enqueue<HangfireTasks>(x => x.SendEmail(subject, body, to)); 

Wo bin ich in einer Zeichenfolge für Thema, Körper und zu übergeben.

Das ist also der schwierige Teil. Ich möchte diesen Ruf nachahmen, damit ich das Thema, den Körper und die Saiten betrachten kann.

Ich habe diesen Code, der funktioniert und ich kann die Saiten, die ich will, aber es ist super hässlich.

var hangfireMock = new Mock<IHangfireWrapper>(); 

string body = null; 
string subject = null; 
string to = null; 

hangfireMock.Setup(x => x.Enqueue(It.IsAny<Expression<Action<HangfireTasks>>>())) 
    .Callback<Expression<Action<HangfireTasks>>>(expr => 
    { 
     object parameters = ((ConstantExpression)((MemberExpression)((MethodCallExpression)expr.Body).Arguments[0]).Expression).Value; 
     body = (string)parameters.GetType().GetField("body").GetValue(parameters); 
     subject = (string)parameters.GetType().GetField("subject").GetValue(parameters); 
     to = (string)parameters.GetType().GetField("to").GetValue(parameters); 
    }); 

Gibt es einen besseren/kürzeren Weg, dies zu tun? (macht dieser Code überhaupt Sinn?)

+0

Ich sehe verdächtig so aus, als ob Sie versuchen, eine Drittanbieterbibliothek zu testen. Wenn das so ist, wird das allgemein als schlechte Form angesehen, da A) es schwer ist, B zu tun. Wenn du etwas findest, kannst du es nicht wirklich reparieren. Melden Sie Fehler, die Sie gefunden haben, aber machen Sie sich keine Sorgen, sie zu testen. –

+0

Wir verwenden Hangfire, um unsere E-Mails abzufeuern. Ich teste gerade, dass Betreff, Nachrichtentext und Adressen der E-Mail genau das sind, was wir erwarten. Wir fügen Hangfire in eine Schnittstelle ein, so dass wir Aufrufe dazu simulieren können. – Devcon

+2

Eine weitere Möglichkeit zum Testen Ihres Codes, der mit Hangfire funktioniert, besteht darin, einen IBackgroundJobClient in die Klasse zu injizieren, die die Enqueue-Methode aufruft. Dieser Ansatz wird in der Hangfire-Dokumentation beschrieben: http://docs.hangfire.io/en/latest/background-methods/writing-unit-tests.html – Darrel

Antwort

3

Was Sie tun, könnte für Ihre Version des Compilers arbeiten und solange Sie immer genau das Lambda bilden.

Hier sind einige Beispiele lambdas, für die es nicht funktionieren wird:

x => x.SendEmail("subject", "body", "to") 
x => x.SendEmail(subject, subject, to) 

Was sollten Sie stattdessen tun ist, um die Arguments des SendEmail Anruf anzunehmen und jeder von ihnen beurteilen durch einen Lambda-Ausdruck für sie zu schaffen und Kompilieren es dann:

var arguments = ((MethodCallExpression)expr.Body).Arguments; 
subject = Expression.Lambda<Func<string>>(arguments[0]).Compile()(); 
body = Expression.Lambda<Func<string>>(arguments[1]).Compile()(); 
to = Expression.Lambda<Func<string>>(arguments[2]).Compile()(); 

einen Ausdruck zu kompilieren ist relativ teuer, so dass es sinnvoll wäre, die Ausdrücke anstatt zu interpretieren. You have that choice on .Net Core und Sie werden wahrscheinlich auch in einer zukünftigen Version von .Net Framework.

Verwandte Themen