0

Hi So I have created an interface for datetime like this:

public interface ITimeProvider<T> { T Now { get; } string ToShortDateString(); } 

And then I have one implamentation of that interface like this:

public class DateTimeProvider : ITimeProvider<DateTime> { private DateTime _date; public DateTime Now { get { return DateTime.Now; } } public DateTimeProvider() { _date = new DateTime(); } public string ToShortDateString() { return _date.ToShortDateString(); } } 

Then I am using it in my main unit and want to use property injection but i ran into some problems, here is a snap of what I have:

public class Atm : IAtm { public ITimeProvider _timeProvider { get;set; } } 

This doesn't work as I don't specifiy a type. I could just do

public ITimeProvider<DateTime> _timeProvider { get;set; } 

But then I wouldn't be able to use another timeprovider. I have also considered(and is the only solution I could come up with) is to make ATM generic so something like this

 public class Atm<T> : IAtm { public ITimeProvider<T> _timeProvider { get;set; } } 

But then I feel like I can't use property injection, is there any other way I can do this so I will be able to test it?

6
  • "but I ran into some problems". "doesn't work as I don't specify a type", but you have registered your implementation of the interface with the injection container I assume? Commented Oct 29, 2015 at 13:58
  • 2
    “But then I wouldn't be able to use another timeprovider” – How likely is it that you are considering using a different type than DateTime to represent dates and times? Commented Oct 29, 2015 at 14:04
  • It isn't but I do want to mock it out for testing Commented Oct 29, 2015 at 14:08
  • 2
    You only need to be able to mock DateTime.Now for testing (which you are with that time provider). There is no reason to encapsulate the whole DateTime type; you can just create the datetime objects the way you need it for testing purposes. Commented Oct 29, 2015 at 14:09
  • @Sumsar1812 - Can you please explain why do you need DateTime to be a generic type parameter? Commented Oct 29, 2015 at 14:19

2 Answers 2

3

The thing you are abstracting is the DateTime.Now function not the DateTime datatype, you can keep the implementation the exactly the same but just fix the type.

public interface ITimeProvider { DateTime Now { get; } string ToShortDateString(); } public class DateTimeProvider : ITimeProvider { public DateTime Now { get { return DateTime.Now; } } public string ToShortDateString() { return Now.ToShortDateString(); } } public class RemoteTimeProvider : ITimeProvider { public DateTime Now { get { using(var client = new WebClient()) { var timeString = client.DownloadString(http://www.timeapi.org/utc/now); return DateTime.Parse(timeString, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal).ToLocalTime() } } } public DateTimeProvider() { } public string ToShortDateString() { //ToDo } } 

Also, I don't really get what your ToShortDateString() does, it does not take in a parameter and it just uses the value returned from new DateTime().

Sign up to request clarification or add additional context in comments.

Comments

1

Use Fakes to be able to unit test system or other assemblies not under your control.

[TestClass] public class TestClass1 { [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); }; // Instantiate the component under test: var componentUnderTest = new MyComponent(); // Act: int year = componentUnderTest.GetTheCurrentYear(); // Assert: // This will always be true if the component is working: Assert.AreEqual(fixedYear, year); } } } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.