Reputation: 9389
I have a domain service
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));
}
}
Here , the methods
So what will my unit test for BlobService look like ?
?
Upvotes: 0
Views: 1061
Reputation: 28121
These are some relevant DDD testing principles I've learned along the way:
(Again, these are specific to my project - YMMV.)
So with that in mind, here's how I would test your class. (Note that I have killed the static DomainEvents
class and replaced it with IBus
because it makes testing way easier in my experience.):
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));
}
}
Upvotes: 0
Reputation: 2121
I see no value in testing if repo methods are called. Using this feature of mocks is useful when we test a component that is intended to interact with (be a wrapper of) some external system. This is not the case here.
Tests, whatever type you use, should have AAA structure. Arrange - prepare some test data/state. Act - call your service. Assert - verify the outcome (final state) is correct. You use domain events - this means testing also if correct events were raised. If you used Event Sourcing - you would do arrange part as playing events and assert part would contain only checking events raised.
Integration test are slower then unit test. You need them if your persistence leaks into the domain or contrary. For example, when you rely on lazy loading features of ORM (which is not very DDD-like by the way) or use stored procedures.
Well, don't assume too quickly that it doesn't leak ;)
Upvotes: 1