I would like to ask 2 questions about the modularization of an F# file. The code is just a working example of prime factorization, but that's not the main topic. I have a main file (PrimeFactors.fs), a different file for its mocked version (PrimeFactorsMock.fs), and a test file (PrimeFactorsTests.fs):
namespace PrimeFactors module PrimeFactors = type IPrimeChecker = abstract member IsPrime : int64 -> int64 -> bool type PrimeFactors() = interface IPrimeChecker with member this.IsPrime number i = number % i = 0L member this.CheckPrimes number i acc = match i with | _ when i > (number |> float |> sqrt |> int64) -> number::acc | _ when (this :> IPrimeChecker).IsPrime number i -> this.CheckPrimes (number / i) i (i::acc) | _ -> this.CheckPrimes number (i + 1L) acc member this.Of number = if number = 1L then [||] else this.CheckPrimes number 2L  |> List.toArray
namespace PrimeFactors open PrimeFactors module PrimeFactorsMock = type PrimeFactorsMock() = inherit PrimeFactors() let mutable stepCount = 0L interface IPrimeChecker with member this.IsPrime number i = stepCount <- stepCount + 1L number % i = 0L member this.StepCount number = stepCount <- 0L this.Of number |> ignore stepCount
namespace PrimeFactors open PrimeFactors open NUnit.Framework open FsUnit open PrimeFactorsMock [<TestFixture>] module PrimeFactorTests = [<TestCase(1L, [||])>] [<TestCase(2L, [|2L|])>] [<TestCase(3L, [|3L|])>] [<TestCase(4L, [|2L; 2L|])>] [<TestCase(6L, [|3L; 2L|])>] [<TestCase(8L, [|2L; 2L; 2L|])>] [<TestCase(16L, [|2L; 2L; 2L; 2L|])>] [<TestCase(773L, [|773L|])>] [<TestCase(8L, [|2L; 2L; 2L|])>] let prime_factors_of_number number expect = PrimeFactors().Of number |> should equal expect [<TestCase(1L, 0L)>] [<TestCase(4L, 1L)>] [<TestCase(773L, 26L)>] let step_count_of_number number stepCount = PrimeFactorsMock().StepCount number |> should equal stepCount
What I like in that solution it's mock version is separated rightly from the initial class. So I only have to redefine
IPrimeChecker.IsPrime, not the
this.CheckPrimes, and possible all the inner functions. So I made
IsPrime, and only
IsPrime, virtual. It's a poor man's mocking.
My question is about mocking with object expression if that could be achieved without creating the PrimeFactorsMock.fs, and less coding. If we redefine the whole PrimeFactorsMock in the test file, it doesn't count (at least make it smaller). The goal is to make the
IsPrime function interchangeable in the test file without much hassle.
The other question is I would like to use active patterns for
IsPrime. So I can use pattern matching with
(|Prime|NonPrime|) in the
this.CheckPrimes part. Restriction is that have to be same as interchangeable as the already implemented virtual