forked from fsprojects/FSharp.Data.SqlClient
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathunit-testing.fsx
More file actions
94 lines (74 loc) · 3.17 KB
/
unit-testing.fsx
File metadata and controls
94 lines (74 loc) · 3.17 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
(*** hide ***)
#r @"..\..\bin\net462\FSharp.Data.SqlClient.dll"
#r @"..\..\packages\Test\xunit\lib\net20\xunit.dll"
#r "System.Transactions"
open FSharp.Data
open System
[<Literal>]
let connectionString = @"Data Source=.;Initial Catalog=AdventureWorks2012;Integrated Security=True;TrustServerCertificate=true"
(**
Unit-testing
===================
Often there is a need to test business or presentation logic independently of database.
This can be archived via [Repository](http://martinfowler.com/eaaCatalog/repository.html) pattern.
*)
//Command types definitions
type GetEmployeesByLevel =
SqlCommandProvider<"
SELECT P.FirstName, P.LastName, E.JobTitle
FROM HumanResources.Employee AS E
JOIN Person.Person AS P ON E.BusinessEntityID = P.BusinessEntityID
WHERE OrganizationLevel = @orgLevel
", connectionString>
type GetSalesChampion = SqlCommandProvider<"
SELECT TOP 1 FirstName, LastName
FROM Sales.vSalesPerson
WHERE CountryRegionName = @countryRegionName
ORDER BY SalesYTD DESC
" , connectionString, SingleRow = true>
//Repository inteface
type IRepository =
abstract GetEmployeesByLevel: int16 -> list<GetEmployeesByLevel.Record>
abstract GetSalesChampion: country: string -> option<GetSalesChampion.Record>
//Production implementation
type Repository(connectionString: string) =
interface IRepository with
member __.GetEmployeesByLevel(orgLevel) =
use cmd = new GetEmployeesByLevel(connectionString)
cmd.Execute(orgLevel) |> Seq.toList
member __.GetSalesChampion( region) =
use cmd = new GetSalesChampion(connectionString)
cmd.Execute(region)
//logic to test
let whoReportsToCEO(db: IRepository) =
[ for x in db.GetEmployeesByLevel(1s) -> sprintf "%s %s" x.FirstName x.LastName, x.JobTitle ]
let bestSalesRepInCanada(db: IRepository) =
db.GetSalesChampion("Canada")
//unit tests suite
module MyTests =
//mock the real repo
let mockRepository = {
new IRepository with
member __.GetEmployeesByLevel(orgLevel) =
if orgLevel = 1s
then
[
//Generated record types have single constructor that include all properties
//It exists to support unit-testing.
GetEmployeesByLevel.Record("David", "Bradley", JobTitle = "Marketing Manager")
]
else []
member __.GetSalesChampion( region) =
use cmd = new GetSalesChampion(connectionString)
cmd.Execute(region)
}
//unit test
let ``who reports to CEO``() =
let expected = [ "David Bradley", "Marketing Manager" ]
assert (whoReportsToCEO mockRepository = expected)
//replace assert invocation above with invocation to your favorite unit testing framework
//fro example Xunit.NET: Assert.Equal<_ list>(expected, actual)
//unit test
let ``best sales rep in Canada``() =
let expected = Some( GetSalesChampion.Record("José", "Saraiva"))
assert (bestSalesRepInCanada mockRepository = expected)