Design pattern for application time?

If you create systems in which business processes depend on time [1], you cannot use DateTime.Now or the like in your code, since you will have to deal with tests, for example, future scenarios of the end of the month or the end of the year. Changing the operating system time is usually not an option when using SSL certificates and because it is difficult to do it right for a distributed system.

One option is to create a singleton service, available on all systems, that returns the current time. In production, he could return DateTime.Now , and in tests he could return playing time, like February 28, in the script for the end of the month.

But is there a better way to do this? Like a more database-based approach, since it leads to increased productivity? Or would you enable distributed cache? Is there any known design pattern for this?

[1] typical example: business processes implemented by the insurance system, the main banking system, ...

+6
source share
5 answers

I came to the conclusion that the following approach would work:

Unit tests:

  • Mocking structure to control time at will

User-driven integration tests, tests, and manufacturing:

  • Dependency inclusion used to introduce a test approach or production approach.
  • Testing approach: Ask the NTP server for how long. This NTP server will be connected to all relevant applications, and not to servers that have their own. The NTP server will have a standard interface that allows programs, such as a test portal or admin tools, to modify it as needed.
  • Production Approach: Request the system time, which is the time from an NTP server connected to all servers.

Here is the C # code for calling an NTP server: calling an NTP server with C #

Lars

0
source

One way to solve this problem is to create a clock interface :

 public interface IClock { DateTime Now { get; } } 

And use this interface throughout your code instead of DateTime.Now . In production, you will use your canonical implementation (or UTC option):

 public class SystemClock implements IClock { public DateTime Now { get { return DateTime.Now; } } } 

You can, for example, use SystemClock by default in all classes that need IClock , and allow other implementations to be entered through constructors or setters.

In tests, you can create a test implementation or mock it with a mockery.

+4
source

You can learn Microsoft Fakes to achieve what you are talking about.

See this slightly modified example;

 [TestMethod] public void TestCurrentYear() { int fixedYear = 2000; // Shims can be used only in a ShimsContext: using (ShimsContext.Create()) { // Arrange: // Shim DateTime.Now to return a fixed date: System.Fakes.ShimDateTime.NowGet = () => { return new DateTime(fixedYear, 1, 1); }; // Act: int year = DateTime.Now.Year; // Assert: Assert.AreEqual(fixedYear, year); } } 

The advantage here is that you do not need to change the code that DateTime uses to make it available for testing.

+2
source

Where date and time are critical and complex (especially due to time zones and DST), which, it seems to me, take place in the industries you mentioned, you can avoid DateTime in favor of Noda time .

Noda Time has built-in module testing capabilities fooobar.com/questions/260874 / ...

+2
source

For unit testing, you should be able to drown out anything, including time. Some mocking frameworks (e.g. Microsoft Shims ) allow you to override DateTime.Now behavior.

To test the integration / system, which I did in the past, we use the configuration parameter for each system component, which sets the DateTime offset for this component used with a real DateTime. This can be specified by the undocumented app.config parameter, where if the parameter is absent, normal behavior is applied. You must be careful, however, this does not lead to any vulnerabilities.

+1
source

Source: https://habr.com/ru/post/955974/


All Articles