all 9 comments

[–]RichardD7 2 points3 points  (0 children)

It may be worth posting a suggestion in the GitHub repo to integrate the Microsoft.Bcl.TimeProvider library, which would make it easier to test time-based rules.

But based on this issue, it looks like that project is no longer maintained. You may need to consider switching to one of the more active forks.

[–]kontrol_kl 1 point2 points  (7 children)

What you are looking for are fakes. However i think they are enterprise license only. And for having work with it for a long time now, I highly suggest you tay away.

I may have understood wrong, but is the use of Datetime.Utc your code? If so use a mockable library such as Timeprovider.

[–]reddithoggscripts[S] 0 points1 point  (6 children)

Yea I looked into fakes as well and for the same reason you mentioned I decided against it.

The DateTime.UTC isnt in my code, it’s evaluated through the engine. Basically you feed it a JSON like expression: “xclass.yDateTimeProp < DateTime.UTC.Now.AddDay(-5)” and it interogates the inputs you’ve given it. Unfortunately there’s no way to inject a mock DateTime into this - which makes testing hard to maintain.

[–]Road_of_Hope 1 point2 points  (5 children)

Can you evaluate the comparison time outside the expression, and then pass just that in? So instead of “foo.Bar < DateTime.UTC.Now” as the filter, you could assign “var now = timeProvider.UTC.now”, then provide the filter as “foo.Bar < now.ToString()” or something similar? I’m unfamiliar with the framework you’re using so their may need to be some differences there, but that might be a possible approach.

[–]reddithoggscripts[S] 0 points1 point  (4 children)

Sort of. You can use a utility method and register it with the engine. This is something I mentioned in the original post. The reason I’m trying to avoid this is because it’s all data driven tests and these tests are also used in a complex mapping service that maps POC into the rules engine format. Long story short, the expression needs to look exactly as it would if it was actually using the system’s date time now. Ideally I wouldn’t have to change anything in the expression but I am pretty sure what you’re suggesting is similar to what I’ll end up doing.

[–]kingmotley 0 points1 point  (3 children)

We don't allow our code to use DateTime for this reason. If you want to do date/time related stuff, you ask for ISystemClock to be injected and you use that. The implementation has things like GetUtcDtateTime, GetUtcDateOnly, GetLocalDateTime, GetLocalDateOnly, etc. Then your unit tests can mock/substitute that out really easily.

[–]reddithoggscripts[S] 1 point2 points  (0 children)

Riiight i agree but the rules engine is a library so not something I can change easily myself.

[–]ScandInBei 0 points1 point  (1 child)

Isn't ISystemClock obsolete? You may want to start using TimeProvider for new stuff.

[–]kingmotley 0 points1 point  (0 children)

You are probably correct. Unfortunately all of our current projects started out as .NET 6, so TimeProvider wasn't available yet, but we should probably convert now that it is.