Injecting a dependency into a domain model
我有一个域模型,它有一个
现在我正试图创建一个
为此:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | public class LogItem : KeyedEntityBase { public LogItem(string message, string description, string status) : this() { Message = message; Description = description; Status = status; } private LogItem() { } public DateTime OccurredOn { get; set; } public string Message { get; set; } public string Description { get; set; } public string Status { get; set; } } |
这是:
或者:
1 | var newItem = LogItemFactory.CreateNewLogItem("message","desc","status"); |
或者:
1 2 3 4 5 6 7 8 9 10 | public LogItem(string message, string description, string status) : this() { Message = message; Description = description; Status = status; var clock = ObjectFactory.GetInstance<IClock>(); OccurredOn = clock.Now(); } |
最简单的方法是在
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | public class LogItem : KeyedEntityBase { public LogItem(string message, string description, string status) : this() { Message = message; Description = description; Status = status; } private LogItem() { } internal LogItem(string message, string description, string status, DateTime dateTme) : this(message, description, status) { OccuredOn = dateTime; } public DateTime OccurredOn { get; set; } public string Message { get; set; } public string Description { get; set; } public string Status { get; set; } } |
然后使用
然后在你的测试中(只有那里),你可以写:
1 |
我很清楚,很多人会说,你不应该仅仅为了使域模型具有可测试性而向域模型中添加代码,但我个人认为,当实践表明这一点时,我并不认为这一论点太严重。
尝试以下方法:
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 | //your object public class LogItem { public LogItem(string message, string description, string status) { Message = message; Description = description; Status = status; } public System.DateTime OccurredOn { get; set; } public string Message { get; set; } public string Description { get; set; } public string Status { get; set; } } public interface ILogFactory { LogItem CreateNew(string message, string description, string status); } public class LogFactory: ILogFactory { private readonly IClock clock; public LogFactory(IClock clock) { Requires.IsNotNull(clock,"clock"); this.clock = clock; } public LogItem CreateNew(string message, string description, string status) { var item = new LogItem (message, description, status); item.OccurredOn = clock.Now(); return item; } } public interface IClock { System.DateTime Now(); } |
为了测试:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | using NSubstitute; // see http://nsubstitute.github.io/ using NUF = NUnit.Framework; [NUF.TestFixture] public class LogFactoryTest { [NUF.Test]public void CreateNew_should_call_now() { var clock = Substitute.For<IClock>(); var fac = new LogFactory(clock); fac.CreateNew("a","b","c"); clock.Received().Now(); } [NUF.Test]public void CreateNew_should_set_correct_value() { var clock = Substitute.For<IClock>(); var now = new System.DateTime(2014, 1, 15, 18, 0, 0); clock.Now().Returns(now); var fac = new LogFactory(clock); LogItem log = fac.CreateNew("a","b","c"); NUF.Assert.That(log.OccurredOn, NUF.Is.EqualTo(now)); } } |