Showing posts with label Mocking. Show all posts
Showing posts with label Mocking. Show all posts

Wednesday, January 4, 2017

Trying to Get Foq Working with NUnit Test Runners (RESOLVED)

I've been exploring mocking using F# (Simple Mocking in F#... & More Simple Mocking...). At some point, mocking gets more complex, and it makes sense to use a mocking library. I've been looking at Foq but have had some issues getting things to work. It turns out the problem seems to lie with the NUnit test runners.

I'm looking for advice on how to get this working, so comments are very welcome here. (And I have tried searching on Google, but the keywords I've been using have not returned anything relevant.)

*** Update (Resolution) ***
When I tweeted out this article, I got lots of responses. That's one thing I really like about the F# community: they are always ready to help. It turns out the issue was easy to resolve. I just needed to change the F# Runtime version from 4.0 to 3.0 in the project settings:


After that, the tests ran successfully. Feel free to read the rest of this article if you're curious, but it turns out the solution was pretty simple (once you know about it).

If you'd like to grab the project, you can get it on GitHub: jeremybytes/mocking-tests.

The Problem
When I started exploring testing using FsUnit, I got error messages when I tried to use Foq. To narrow things down, I eliminated as many variables as possible. That meant using the sample from the "Foq.Usage.fsx" file that came down when grabbing the package from NuGet.

To setup the project, I created a new F# library. Then from NuGet, I got the following packages: "Foq" (v1.7.1), "NUnit" (v3.5.0), and "NUnit3TestAdapater" (v3.6.0).

The Sample Test
Here's the sample test copied from the usage file into the code file (in Library1.fs):


This test should pass, but it fails in the Test Explorer:


Here's the error message:
Method not found: 'Foq.ResultBuilder`2<!0,!!0> Foq.Mock`1.Setup(Microsoft.FSharp.Core.FSharpFunc`2<!0,Microsoft.FSharp.Quotations.FSharpExpr`1<!!0>>)'.
Unfortunately, I'm not familiar enough with code quotations in F# (and parsing expressions in general) to be able to understand this message. So I did some more work to try to narrow things down.

Verifying NUnit
First, I verified that NUnit and the NUnit3TestAdapater actually work with the F# library. For this, I simply added another test (in Library1.fs):


And the test runner has no problems with this. Here's the passing test and the failing test output:


Working Foq Test in F# Interactive
The reason I think the test runner might be the problem is that I was able to successfully run the test in F# interactive. To try to eliminate variables, I created a new script file with just the following (in Script.fsx):


When executing this script, I get the following output:


This shows me that we're not getting any errors just by running this script with Foq and the code quotation.

Testing for Failure
Just to make sure that things were working, I decided to invert the test. I changed the mock object so that it would return "false" instead of "true", but I left the assertion unchanged:


When executing this script, we get the NUnit test failure message:


So that is working as expected.

Trying the Console Runner
My next step to try to isolate this to the test runners was to try the NUnit Console Runner. For this, I grabbed the "NUnit.ConsoleRunner" (v3.5.0) package.

When running the library tests from the command line, I got the same result: 1 passed, 1 failed:


And digging through the output file, I came across the same message as when running the tests in Visual Studio.

Any Ideas?
So the question for the F# gurus out there: Is there a way to get the NUnit test runners to work with this Foq example?

Unfortunately, I'm not at the point where I can parse the error message, so I don't know if it's a simple fix, or something that won't work because of the way that the NUnit test runners are implemented.

*** Update (Resolution) ***
When I tweeted out this article, I got lots of responses. That's one thing I really like about the F# community: they are always ready to help. It turns out the issue was easy to resolve. I just needed to change the F# Runtime version from 4.0 to 3.0 in the project settings.

Why I Care
I know that some folks are saying, "Well just run your tests as a script." And that would work for some scenarios.

What I'm exploring is how to use F# for testing C# code. For that, I want the test runner experience to be as seamless as possible. I'm currently using NUnit, and I prefer to have the integrated test runner in Visual Studio. So that's why I'm looking into this further.

I'll be sure to post solutions because I'd really like to get this working, and I'm sure I'm not the only one.

Happy Coding!

Tuesday, December 27, 2016

More Simple Mocking in F# with Object Expressions

A few weeks ago, I did some simple mocking in F# by using object expressions. I thought this was a really cool option, particularly since most of my mocking requirements have been pretty simple. I ended up doing some more experimentation and found a couple more things that work great in simple scenarios.

So today, we'll look at how we can provide different results based on different parameters and how we can count the number of times a method is called.

As a side note, I have been doing some experimentation with Foq (I use Moq pretty extensively in the C# world). Unfortunately, I've been failing at the implementation; my F# skills need some work. Once I get that figured out, I'll show how that is better option when dealing with more complex scenarios. [Update 12/30/2016: It looks like my issues are related to the test runner, not my F# skills. More to come.]

[Update 1/4/2017: It turned out to be a runtime version issue. Read more here: Trying to Get Foq Working with NUnit Test Runners.]

Simple Method Mocking
In the last article, we looked at mocking using a simple object expression:

Simple Method Mocking with an Object Expression

This scenario is pretty simple. We have an interface (ISolarService) which has a single method (GetServiceData). The object expression (inside the curly braces) allows us to specify that if anyone calls the "GetServiceData" method, it should return the results in our "goodData" object (this is just a string with JSON data that's specified at the top of the test class).

Date/DateTime Functions
I made another change to the code since we looked at it last time. Notice that the test function above has calls to "date" and "dateTime". I created these functions to adjust the syntax a bit. Previously, I was creating DateTime objects directly, and the code looked like this:

Code with Original DateTime objects

I played around with syntax a bit and came up with these two functions:


These functions wrap a call to the DateTime constructor. I'm not sure if I'm 100% happy with this, but I do like how things look in the calling code when we call "date" and "dateTime". It seems to fit in better with the F# style.

Along with this, I added the intermediate items "requestDate" and "expected". By adding these, I could eliminate the parentheses later on. Again, I'm not sure if this is a good way to go, but I do like the syntax a bit better here.

Different Parameters, Different Results
While I was exploring mocking, I ran across a sample that showed a really easy way to have different result sets returned from a method based on the parameter. (Sorry, I didn't keep track of the article, so I can't point back to it.)

To have different result sets come back, we can expand our object expression to use pattern matching in the body of the member:

Simple Method Mocking with Pattern Matching

In this code, we don't ignore the parameter. Instead, we grab onto it so we can match against it.

So if we pass in the "requestDate" (which is Nov 24th 2016), we return our "goodData" string. But if we pass in any other value, we return our "badData" string.

This is strictly not necessary for this particular test, but if we had a shared mock object, it could be useful in providing different results for different tests or parameters. (It would also be useful for property-based testing, but that's a topic for another time.)

So we can expand our object expression to be a bit more flexible. And it doesn't take much code to do this (and that makes me happy).

Counting Method Calls
Another area where I've used mocking is to count the number of times that a method is called. This is primarily to check to see if a client-side cache is working, i.e. multiple calls to the client method should only result in a single service call.

With Moq (and Foq), we can do this by using the "Verify" method. And I've done this quite a bit with Moq in my C# code. For a simple scenario (like we have with the Sunrise/Sunset library), we can do the counting manually with just a little bit of code.

Here's an example:

Simple Method Call Counting

Each time the "GetServiceData" method is called, we increment the "callCount" variable. To test this, we call "GetSunset" twice with the same parameter. We don't care about the results of those method calls, so we just ignore them.

But then we check the "callCount" to make sure that the service method inside our mock object was only called one time.

Here's a test that shows something similar:

Simple Method Call Counting

In this case, we call "GetSunset" with different parameters, so we expect that the service is called twice.

There are a couple things I'd like to change about this code. I would like to have the counter (callCount) be part of the object expression. In the current state, it seems to "leak" since the counter is completely separate from the object.

Another thing about this code is that it only works with a single method. If the mock object had multiple members that we wanted to track, then things would get quite a bit more complicated.

I'm sure that I could write that code, but what I'd really be doing is writing my own mocking framework. And that's something I definitely don't want to do. I'd rather leave that to the experts who have already done this.

Mocking Frameworks
These examples work great with very simple scenarios. In this case, we only have a single method in the interface. But as soon as we have multiple methods, it's pretty common to only want to provide mock implementations for only one or two of them. In addition, we may want to track calls to multiple methods. That's where our code breaks down.

I've taken a quick look at Foq (and even Moq) in my F# tests, and that's where I found that my F# skills are still lacking. I seem to be doing okay at compile time (everything builds), but I'm getting errors at run time. So I need to figure out where I'm going wrong. I'm pretty sure it's around the code quotations. Once I get that worked out, I'll do some more exploration and write up my results.

[Update: 12/30/2016: It looks like the problems I've run into with Foq are related to the test runner that I'm using and not because of my F# skills. I can get test code to run in the REPL, but I get exceptions with using the NUnit test adapter. I've got a bit more to figure out here.]

[Update 1/4/2017: It turned out to be a runtime version issue. Read more here: Trying to Get Foq Working with NUnit Test Runners.]

Wrap Up
The more I work with it, the more I like the idea of using F# for testing my C# code. Unit tests are generally functional in nature: discrete inputs/outputs, no side-effects. So it seems like a good fit. Plus it gives me a chance to get better at F# using small steps.

One thing about being a programmer: it's impossible to get bored.

Happy Coding!

Sunday, November 27, 2016

Simple Mocking in F# with Object Expressions (I Like This)

Last time I talked about how I had some mixed feelings about testing C# code using FsUnit. I took the last example a step further and added mocking to the FsUnit test. I really like how easy F# makes it to do simple mocking.

Here's a reminder of the test comparison from last time:

FsUnit testing GetSunset

NUnit testing GetSunset

I had some mixed feelings about this (and I'm still working on them a bit). But I decided to take this a step further and add mocking.

Mocking with C# Code
The code above uses hard-coded data in the production file. The next step is to add an actual service call. But, of course, this messes with the tests.

We don't want to have a service call in our tests, so in the code, we add a property to our class so we can do some property injection. But then we need to create a mock of the object.

Here's the interface we need to mock:


And here's a test in NUnit that uses Moq to mock up the interface:

NUnit with Mock Interface

I've used Moq quite a bit in the past, and I've found it to have the features that I've need in my code.

With that said, the setup for Moq takes a bit of getting used to. But what the second line of this test is saying is "If someone calls the 'GetServiceData' method on this object (no matter what parameter), please return them the 'goodResult' object." The "goodResult" object is the JSON string with our test data.

Then a bit further down, we assign the "serviceMock.Object" to the property on our class. We have to use "Object" because this is how we pull the "ISolarService" object out of our "Mock<ISolarService" object.

This is code that I'm used to seeing. But I found it can be a bit better in F#.

Simple Mocking with F#
First, I started to look at Foq (which is an F# version of Moq). But with a little more searching, I found that I didn't even need to use a mocking framework for the simple call that I needed here.

Here's the same test in F#:

FsUnit with Mock Interface

Take a look at the "mock" item at the beginning of the function. This is an Object Expression. By using this, we have an object that behaves like the mock we created above. If someone calls the "GetServiceData" member on the object (with any parameter (as denoted by the '_' that we don't use later)), we want to return "goodData", our JSON string.

Then a few lines down, we assign the mock to the "Service" property. (And we don't have to use the "Object" property like we did with Moq.)

One other thing that I did to this code that cleans it up a bit: I removed the "new" keywords before all of the constructors. This is optional in the F# world, and it makes things a bit better to read.

Wrap Up
I'm still working on readability. This is a key attribute of unit tests. I really like the Object Expression syntax that allows us to create simple mocks very easily. This is more readable than using Moq in C#.

So I'll keep working through this. If you have any suggestions, feel free to let me know. I'm always looking for tips from folks who have more experience with this than I do.

Happy Coding!

Monday, June 27, 2016

Unit Test Factory Methods: Return an Interface or a Mock?

Had a great question today regarding what to return when using factory methods with unit tests:
Should a unit test factory method return the interface or a mock of the interface?
The best way to look at this is to look at an example. Let's say that we have a class ("DataParser") that take an "ILogger" as a constructor parameter. This class would look like this:


Now in our tests, we want to test the "ParseData" method behavior. But we need an "ILogger" to satisfy the constructor parameter. In some situations we just need the "ILogger" for construction (technically, behaving as a stub), and for other situations, we need to assert against the "ILogger" (behaving as a mock).

So if we have a factory method, should it return "ILogger" or "Mock<ILogger>"? Here's what the options would look like:


Note: this code is using Moq for mocking. This mocking framework has met most of my needs over the years.

Disclaimer
Before going any further, I want to say that my "recommendation" is just my opinion -- this is the way that I prefer to do this. Roy Osherove (who wrote the excellent The Art of Unit Testing) says that we need to make a clear distinction in our code between a stub and a mock. (Also, he's not a fan of Moq as a mocking framework because it does not make that distinction.)

What I've found is that in the tests that I've written, that distinction is unneeded. So, I've chosen a direction that (hopefully) minimizes confusion and enhances readability of the code.

Picking One
One option would be to keep both of these methods and use "GetLogger" when we need a stub and "GetMockLogger" when we need a mock. I would rather minimize the number of factory methods that I have unless they are really needed, so I'm going to pick one.

Note: it's perfectly valid to keep both of these; however, I might recommend having the "GetLogger" method call the "GetMockLogger" method so that we are only creating mocks in one place.

So, let's look at both options, and then I'll give you my preference.

Option 1: Returning the Mock<ILogger>
Let's start by looking at a factory method that returns the mock object:


A test that needs a stub would look like this:


Notice that when we create the "DataParser" object on the second line, we need to use the "Object" property of our mock. This gets the actual "ILogger" object out of our mock so that we can use it as a parameter for our constructor.

I don't really like this. It requires too much knowledge of the mocking framework inside the test. If the test does not care about the mock object, I don't want it to be "polluted" with that knowledge.

Option 2: Returning ILogger
So, what if we have our factory return "ILogger"?


We still create the mock object (because we may still need the in-memory behavior of a mock), but we return the "ILogger" itself from the factory.

Then our test would look like this:


I like this much better. This test does not care about whether we have a mock or a fake (meaning, a real class that implements the interfaces and is used for testing purposes). And I think it lends to the readability: we don't have extra stuff that stops us from reading the code.

But What if We Need a Mock?
There are times that we really need a mock object. For example, in this case, we want to verify that the "ILogger.Log()" method is getting called the right number of times by our "ParseData" method. So what does that code look like?

Returning Mock<ILogger>
If we use the method that returns the mock, then our test could look like this:


In this case, we actually need the mock, because we are calling the "Verify" method on it. In Moq, the "Verify" method lets us check to see if a method was called with certain parameters or called a certain number of times (among other things). In this case, we are checking that the "Log" method is called only one time (that's the "Times.Once()" parameter).

We don't care about the parameters, which is why we have the "It.IsAny<string>()" methods in there. I won't get into the details of those right now. We'll save those for a longer article about mocking.

This code is pretty clean. So, let's look at the other option.

Returning ILogger
We can still use the method that returns "ILogger" here. That's because of one of the features of Moq. Here's what that same test looks like:


Notice that we get the "ILogger" from the factory and then pass it to the "DataParser" constructor. But since we want to use the "Verify" method, and that requires a "Mock<ILogger>" to work, we need to do a little extra work.

The last line of the "Arrange" section uses the "Mock.Get()" method. This is a static method in Moq that allows us to take an interface that has been mocked and get the original mock object back. We can see in this case, we end up with a "Mock<ILogger>", which is just what we need.

The rest of the test, including the call to "Verify" is the same as above.

The Danger
This code seems a little bit dangerous. What if "ILogger" is a fake object (instead of a mock)? Well, this code will throw an exception. "Mock.Get()" will only work with objects that were created with Moq.

This means that if we change the "GetLogger" method to return a fake instead of a mock, all of the tests that need a mock will blow up.

Am I worried about this? Not really. If I need a mock object that I'm running assertions against, then I'm probably extra aware of what's going on in the factory methods.

My Preference
So, my preference is to have a single factory method that returns an "ILogger":


Then my tests look like this:



This gives me the most readable code for the first test (where I just need a stub and don't care about asserting against the "ILogger"). This also makes writing these tests really easy. I don't have to worry about the internals of my mocking framework.

The second test is a bit more dangerous, but because I'm asserting against a mock object, I'm going to be paying closer attention to this anyway. And if I'm writing new tests that assert against the mock object, I'm going to have to know something about the mocking framework. So it makes sense to need that additional knowledge here instead of in the "simple" test.

As I noted above, this is just my preference based on my experience. I've written several different kinds of unit tests (and lots of them), and this "feels" the best to me.

Wrap Up
Your mileage may vary. It is perfectly valid to have *both* factory methods, but I prefer to keep factory methods to a minimum. And as I noted before, the distinction between stubs and mocks is more of a technical one in my world -- having the clear separation between them has not been important.
When you're new to unit testing, you'll come across lots of opinion and even more "best practices". 
Try out the ones that look interesting. If they fit into your environment, then keep them. If they don't fit, then feel free to discard them. This is part of the process of learning what works best for you. And that may be different than what works best for me.

Happy Coding!

Sunday, January 11, 2015

Mocking Current Time with a Simple Time Provider

When dealing with "DateTime.Now", we run into interesting issues when unit testing. We can't rely on our tests to run at any particular "now". This means that to write adequate tests, we have 2 options:
  1. Create tests that use times relative to "now".
    This means that we do things like "DateTime.Now().AddMinutes(10)" to get a time 10 minutes in the future. Unfortunately, this is not always practical in our tests.
  2. Change our calls to "DateTime.Now" so that they instead call some sort of time provider that we can swap out for testing.
The application I'm working on is the rewrite of the legacy application that does simple home automation. (I'm a bit reluctant to keep calling it a rewrite at this point: the new code is in production, and I'm moving forward with different functionality from the original.)

Note: The code for this project is available on GitHub: https://github.com/jeremybytes/house-control. You can see how this code was created by following along with the articles collected here: Rewriting a Legacy Application.

Since this application deals with scheduling, it does have calls to "DateTime.Now". And I've put together several unit tests using Option #1 (creating relative time records), but I've hit the limit on that. In order to adequately test all of the functionality -- which is crucial to moving forward confidently -- I need a way to use an arbitrary time for "now" in the unit tests. So, it looks like we need to move to Option #2.

Looking for Solutions
To try to find a good solution, I started with StackOverflow (as many developers do). I came across a very good answer by Mark Seemann, and he also points to an article that he wrote several years back: Testing Against the Current Time.

These solutions seemed a bit more complicated than I wanted to undertake, and they had some functionality that I didn't need. So I took a slightly different approach. I centralized all of the calls to "DateTime.Now" and then set up a property that uses a time provider interface. This property could be swapped out with a mock object for testing and we could use a real time provider as a default to be used in production runs.

Let's take a look at this code. For this, we'll be walking through a few different commits from the GitHub project.

Finding Calls to DateTime.Now
The first step was to find the calls to "DateTime.Now" in our code and see what we can do to centralize those calls. This code is taken from commit 956aab2 (before making these changes). You don't need to follow along with the source code to see what's happening here, but it's available just in case you'd like to.

First, I found some comparisons between the event time and DateTime.Now:

Schedule.cs

HouseController.cs

These are both checking to see if a time is in the past (okay, the second is technically checking that something is *not* in the past, but we can flip the "if" statement around).

Next, I found a method that checks to see how far the event time is from DateTime.Now:

HouseController.cs

Centralizing DateTime.Now
To centralize the calls to "DateTime.Now" I decided to create some extension methods for this functionality. This was pretty easy to do. I already had a "ScheduleHelper" class that had several static methods in it. So all I had to do was add the new methods and make the class itself "static".

If you're following along, this code is in commit 6523bc0.

ScheduleHelper.cs

For the "DurationFromNow" method, I basically just moved the existing method from the "HouseController" class, made it static, and added the "this" keyword to the parameter. For more information on extension methods, check out the article & video: Quick Byte: Extension Methods.

Then I added a new method that would check to see if the time is in the past. Here's how we used this new method in the code:

Schedule.cs

ScheduleHelper.cs

Since "IsInPast" is an extension method, we can treat it as if it is a method directly on "DateTime". The only other real change to the code is that we inverted the "if" statement in the "RollForwardToNextDay" method so that it can use the "IsInPast" method.

Creating the Time Provider
Now that our calls to "DateTime.Now" are all in one spot, it is easier to swap them out for calls to another object. For this, I created a very simple interface: ITimeProvider.

These updates are in commit ece190d.


Then we need an implementation that we can use in production. This is pretty simple:


This just calls "DateTime.Now". Seems like a bit of an indirect route to get to "now". And it is. We're adding a layer of indirection so that we'll have something we can swap out for testing.

Using the Time Provider
Our calls to "DateTime.Now" are all in the "ScheduleHelper" class. This means that we'll want to use our new time provider in this class. Since this is a static class with static methods, I decided to add a static property that we could use. Here's the property:


The reason the property is set up this way is so that we can use property injection. (For an overview of property injection, check this article: Dependency Injection: The Property Injection Pattern).

The short version is that if we do nothing, this code will use our "CurrentTimeProvider" object (which makes actual calls to "DateTime.Now"). This is what we want when we run our application. But for testing, we can set this property to a fake or a mock time provider.

With the new property in place, we just need to update the places where we were calling "DateTime.Now" so that they use the time provider.

ScheduleHelper.cs

So, our extention methods both use the "TimeProvider" property instead of making calls to DateTime directly.

A Call to DateTime.Today
I was so busy looking for calls to "DateTime.Now" that I missed a call to "DateTime.Today". This is in the "Schedule" class.

Schedule.cs

When we're loading up the schedules from the CSV file, we want to use today's date. This will cause us problems for our testing just like calls to "DateTime.Now" does.

Instead of adding a new method to the "ITimeProvider" interface, I decided to add a couple more methods to the "ScheduleHelper" class since methods from this class are already used throughout the application.

ScheduleHelper.cs

Now we can update the call in the "Schedule" class:

Schedule.cs

Since the "ScheduleHelper" uses the time provider, we'll get the results that we expect regardless of whether we are running our application or running our unit tests with a mock time provider.

Mocking Current Time in Unit Tests
With all this code in place, we haven't changed the behavior of our application (hopefully). But we have given ourselves an injection point that we can use in our unit tests.

Previously, I hit a roadblock in the unit tests when Option #1 (above) was no longer adequate for tests. Because of that, I just left a placeholder to remind me that I had some more work to do (from "ScheduleHelperTests.cs"):


Now that we have our time provider in place, we can create a real test:


For this test, we want a "current time" of January 12, 2015 at 4:35:22 p.m. (We'll take a look at "SetCurrentTime" in just a bit to see how this is set.)

Then we create a record that is "in the past" based on the current time: January 12, 2015 at 3:32:00 p.m. When we roll this to the next day, we'll expect that the value is January 13, 2015 at 3:32:00 p.m. And that's what the rest of this test checks for.

Here's our "SetCurrentTime" method. This is just a method that we have inside our unit testing class.


For this, I'm using Moq as a mocking framework. The first line creates a new mock object based on our interface "ITimeProvider". Then in the "Setup" method, we say that when someone calls the "Now" method on our mock object, we want to return the "currentTime" value -- which happens to be the value that is passed in as a parameter to this method.

Once we have our mock object set up, we assign it to the "TimeProvider" property of our "ScheduleHelper". Now any calls into the "ScheduleHelper" will now use our mock time provider.

A Bit of a Problem
When we run all of our tests, we run into a bit of a problem:


One of our tests fails. And notice, this is not the test that we just modified; this is a completely different test.

Let's re-run just the failed test to see if we can figure out what's wrong:



Now the test passes! Crap. This means that we have some kind of interaction between our tests.

This turns out to go back to our TimeProvider property:


Our property is "static". This means that when we run our unit tests, we only have *one* TimeProvider that's shared with all of our calls. So if one of our tests sets the property to something different (like our new test does), it retains the value for other tests.

I spent quite a bit of time going over different possibilities to fix this. We could make the TimeProvider an instance property rather than a static property, but that would upset a lot of the other code (we may even need to move it to a different class).

A (Not Perfect) Fix
Since this is only causing problems in our tests, I opted for a different solution. At the top of the test classes, I added a "Setup" method that would put the "TimeProvider" back to its default value:


I added this "Setup" method to both the "ScheduleTests.cs" and "ScheduleHelperTests.cs" files. This method runs before every test. It will reset the time provider, and then we can use the "SetCurrentTime" method if we need to override it to something else.

With this in place, we can run all of our tests, and they complete successfully:


This is not an ideal solution, but it works for our current situation. The problem? This is not thread-safe. We could see a problem in a multi-threaded test environment. If our tests kicked off simultaneously on multiple threads, then we could end up with some incorrect values for our static "TimeProvider" property (since there would only be one that is shared across multiple threads).

This is not something that we need to worry about with our current test runner for MS Test, but this could change in the future. In that case, we probably need to go back and re-work the time provider a bit (probably by going to one of Mark Seeman's proposed solutions).

Wrap Up
This is a fairly simple way that we can mock the current time for testing purposes. We were able to centralize our calls to "DateTime.Now", so that made things a bit easier. Then we created a simple interface that we could use as a seam in our code. With this in place, a property allows us to inject a mock implementation for our tests. But if we do nothing (like when our application runs), we'll use the actual time from the "CurrentTimeProvider" object.

I'm always a bit cautious about adding complexity to my applications. There's still something about this solution that doesn't quite sit well with me, but I'll keep working on it.

This definitely gives me the chance to create a whole slew of new unit tests. These will be vital for moving forward with some of the functions I have in mind (like implementing the weekday/weekend schedules).

Now I have a pretty good starting point. Refinements will come as the project progresses. Writing software is a process, and we often learn what works and what doesn't work as we go. The important bit is that we keep learning from our experiences.

Happy Coding!