How do functional programmers test functions that return a unit?
<p><strong>How do functional programmers test functions that return a unit?</strong></p>

<p>In my case, I believe I need to unit test an interface to this function:</p>

<pre><code>let logToFile (filePath:string) (formatf : 'data -&gt; string) data =
    use file = new System.IO.StreamWriter(filePath)
    file.WriteLine(formatf data)
    data
</code></pre>

<p><strong>What is the recommended approach when I'm unit testing a function with I/O?</strong></p>

<p>In OOP, I believe a <a href="http://xunitpatterns.com/Test%20Spy.html" rel="noreferrer">Test Spy</a> can be leveraged.</p>

<p><strong>Does the Test Spy pattern translate to functional programming?</strong></p>

<p>My client looks something like this:</p>

<pre><code>[&lt;Test&gt;]
let ``log purchase``() =
    [OneDollarBill] |&gt; select Pepsi
                    |&gt; logToFile "myFile.txt" (sprintf "%A")
                    |&gt; should equal ??? // IDK
</code></pre>

<p><strong>My domain is the following:</strong></p>

<pre><code>module Machine

type Deposit =
    | Nickel
    | Dime
    | Quarter
    | OneDollarBill
    | FiveDollarBill

type Selection =
    | Pepsi
    | Coke
    | Sprite
    | MountainDew

type Attempt = {  
    Price:decimal
    Need:decimal
}

type Transaction = {
    Purchased:Selection  
    Price:decimal
    Deposited:Deposit list
}

type RequestResult =
    | Granted of Transaction
    | Denied of Attempt

(* Functions *)
open System

let insert coin balance = coin::balance
let refund coins = coins

let priceOf = function
    | Pepsi
    | Coke
    | Sprite
    | MountainDew  -&gt; 1.00m

let valueOf = function
    | Nickel         -&gt; 0.05m
    | Dime           -&gt; 0.10m
    | Quarter        -&gt; 0.25m
    | OneDollarBill  -&gt; 1.00m
    | FiveDollarBill -&gt; 5.00m

let totalValue coins =
    (0.00m, coins) ||&gt; List.fold (fun acc coin -&gt; acc + valueOf coin)

let logToFile (filePath:string) (formatf : 'data -&gt; string) data =
    let message = formatf data
    use file = new System.IO.StreamWriter(filePath)
    file.WriteLine(message)
    data

let select item deposited =
    if totalValue deposited &gt;= priceOf item

    then Granted { Purchased=item
                   Deposited=deposited
                   Price = priceOf item }

    else Denied { Price=priceOf item; 
                  Need=priceOf item - totalValue deposited }
</code></pre>