Sto configurando alcuni test unitari e utilizzo di Rhino Mocks per popolare l'oggetto da testare. Una delle cose che viene derisa è una Task<HttpResponseMessage>
, dal momento che la logica da testare include una chiamata a un HttpClient
per ottenere una risposta asincrona.Come simulare un'attività <> Risultato?
Così ho iniziato a impostare i mock come questo:
var httpClient = MockRepository.GenerateMock<HttpClient>();
var taskFunc = MockRepository.GenerateMock<Func<HttpResponseMessage>>();
var responseTask = MockRepository.GenerateMock<Task<HttpResponseMessage>>(taskFunc);
var response = MockRepository.GenerateMock<HttpResponseMessage>();
httpClient.Stub(c => c.PostAsJsonAsync<IEnumerable<LogMessage>>(Arg<string>.Is.Anything, Arg<IEnumerable<LogMessage>>.Is.Anything)).Return(responseTask);
responseTask.Stub(t => t.Result).Return(response);
response.Stub(r => r.IsSuccessStatusCode).Return(true);
(la "Legge" fase del test sarà quello di creare un'istanza dell'oggetto in fase di test, a passare i httpClient
, ed eseguire un metodo . su di esso il "affermare" verificherà attraverso i mock che prevede chiamate di metodo sono state fatte su di loro)
Facendo un passo attraverso questo in un debugger, c'è un indefinito appendere su questa linea:.
responseTask.Stub(t => t.Result).Return(response);
Non ho molta esperienza con Rhino Mocks o con C# async, quindi potrei trascurare qualcosa di ovvio. L'obiettivo, ovviamente, è che qualsiasi chiamata alla proprietà .Result
restituirebbe la simulazione response
. Ma sembra che il mio tentativo stia forse invocando .Result
che mi aspetterei di aspettare indefinitamente dal momento che è solo un finto, forse?
Qual è il modo giusto per organizzare questo? Essenzialmente ho bisogno di fornire il mio oggetto con un HttpClient
deriso e asserire che un metodo è stato chiamato su di esso con un argomento specifico.
Ho fatto un sacco di beffe di Google circa un anno fa usando MOQ. A meno che non mi sbagli, devi solo sostituire il taskFunc che stai passando nel tuo simulato responseTask. Quindi la funzione fittizia restituisce immediatamente una risposta. – Keith
@ Keith: interessante. Quindi basta creare un vero 'Func' invece di un mock, che restituisce solo? Ho appena provato come tale: 'Func taskFunc = delegate() {return response; }; 'e passa' taskFunc' al simulatore 'responseTask', ma si osserva lo stesso comportamento. –
David
Non penso che sia necessario un compito fittizio. Quello che ti serve è la funzione che viene passata nell'attività, quindi restituirà semplicemente "x". – Keith