मैं निम्नलिखित async कार्यप्रवाह (NUnit + FsUnit के साथ) परीक्षण करना चाहते हैं:जब एफ # async परीक्षण कैसे एक उपयोगी स्टैकट्रेस पाने के लिए कार्यप्रवाह
let foo = async {
failwith "oops"
return 42
}
मैं इसके लिए निम्न परीक्षण लिखा है:
let [<Test>] TestFoo() =
foo
|> Async.RunSynchronously
|> should equal 42
के बाद से foo फेंकता मैं इकाई परीक्षण धावक में निम्नलिखित स्टैकट्रेस मिलती है:
System.Exception : oops
at Microsoft.FSharp.Control.CancellationTokenOps.RunSynchronously(CancellationToken token, FSharpAsync`1 computation, FSharpOption`1 timeout)
at Microsoft.FSharp.Control.FSharpAsync.RunSynchronously(FSharpAsync`1 computation, FSharpOption`1 timeout, FSharpOption`1 cancellationToken)
at ExplorationTests.TestFoo() in ExplorationTests.fs: line 76
दुर्भाग्य स्टैकट्रेस हिरण मुझे बताओ कि अपवाद कहाँ उठाया गया था। यह RunSynchronously पर बंद हो जाता है।
कहीं मैंने सुना है कि Async.Catch जादुई स्टैकट्रेस पुनर्स्थापित करता है, इसलिए मैं अपने परीक्षण समायोजित:
let [<Test>] TestFooWithBetterStacktrace() =
foo
|> Async.Catch
|> Async.RunSynchronously
|> fun x -> match x with
| Choice1Of2 x -> x |> should equal 42
| Choice2Of2 ex -> raise (new System.Exception(null, ex))
अब इस बदसूरत है लेकिन कम से कम यह एक उपयोगी स्टैकट्रेस पैदा करता है:
System.Exception : Exception of type 'System.Exception' was thrown.
----> System.Exception : oops
at Microsoft.FSharp.Core.Operators.Raise(Exception exn)
at ExplorationTests.TestFooWithBetterStacktrace() in ExplorationTests.fs: line 86
--Exception
at Microsoft.FSharp.Core.Operators.FailWith(String message)
at [email protected](Unit unitVar) in ExplorationTests.fs: line 71
at [email protected](AsyncParams`1 args)
यह समय स्टैकट्रैक दिखाता है कि त्रुटि वास्तव में कहां है: [email protected] 71
Async.Catch से छुटकारा पाने और दो विकल्पों के बीच मिलान करने का कोई तरीका है जबकि अभी भी उपयोगी stacktraces हो रही है? एसिंक वर्कफ़्लो परीक्षणों को ढांचा बनाने का कोई बेहतर तरीका है?
मुझे एक ही समस्या और Async था।कैच एकमात्र कामकाज था जिसे मैं –
पाया था, मैंने डॉन सिमे को ईमेल किया है, जिन्होंने सुझाव दिया कि यह एक मौलिक .NET सीमा थी, और 'Async.Catch' एकमात्र विकल्प था। –
@JohnPalmer मुझे जवाब देने की तरह लगता है – mydogisbox