我有域名服务
public class BlobService{
private FooRepository repo;
public BlobService(FooRepository repo){
this.repo = repo;
}
public void DoSomething(int id1,int id2){
var foo1 = repo.Get(id1);
var foo2 = repo.Get(id2);
var valueSomething = foo1.GetValueSomething();
foo2.SetValueSomething(valueSomething );
repo.Save(foo2);
DomainEvent.Raise(new ValueSomethingChanged(foo2));
}
}
这里,方法
那么我的单元测试BlobService会是什么样的?
答案 0 :(得分:1)
如果调用repo方法,我认为测试没有价值。当我们测试一个旨在与某个外部系统进行交互(成为其包装)的组件时,使用这个模拟功能非常有用。这不是这种情况。
测试,无论您使用何种类型,都应具有AAA结构。安排 - 准备一些测试数据/状态。行动 - 致电您的服务。断言 - 验证结果(最终状态)是否正确。您使用域事件 - 这意味着还要测试是否引发了正确的事件。如果您使用事件采购 - 您可以将部分安排为播放事件,并且断言部分仅包含检查事件。
集成测试比单元测试慢。如果持久性泄漏到域中或相反,则需要它们。例如,当您依赖ORM的延迟加载功能(顺便说一下,它不是非常类似DDD)或使用存储过程时。
好吧,不要假设它没有泄漏;)
答案 1 :(得分:0)
这些是我在此过程中学到的一些相关的DDD测试原则:
(同样,这些特定于我的项目 - YMMV。)
所以考虑到这一点,这就是我如何测试你的课程。 (请注意,我已经杀死了静态DomainEvents
类,并将其替换为IBus
,因为根据我的经验,它使测试更容易。):
public class BlobService
{
private IBus _bus;
private IFooRepository _repo;
public BlobService(IBus bus, IFooRepository repo)
{
_bus = bus;
_repo = repo;
}
public void DoSomething(int id1, int id2)
{
var foo1 = _repo.Get(id1);
var foo2 = _repo.Get(id2);
var valueSomething = foo1.GetValueSomething();
foo2.SetValueSomething(valueSomething);
_repo.Save(foo2);
_bus.Publish(new ValueSomethingChanged(foo2));
}
}
[TestFixture]
public class BlobRepositoryTests
{
[Test]
public void DoSomething_RaisesValueSomethingChanged()
{
// Arrange:
var bus = new MockBus(); // just stores the events in a publicly accessible list
var repo = new MockBlobRepository(); // does whatever you need it to do (or use Moq, etc)
var service = new BlobService(bus, repo);
// Act:
service.DoSomething(1, 2);
// Assert:
var @event = bus.Events.OfType<ValueSomethingChanged>().Single();
Assert.That(() => @event.Property1, Is.EqualTo(someExpectedValue));
Assert.That(() => @event.Property2, Is.EqualTo(someOtherExpectedValue));
}
}