After reading several questions/answers about unit testing Entity Framework, I have decided to forgo unit testing for integration testing. I am going in with the philosophy that interacting with the EF context is a "private" action, because it does not need to be unit tested independently of my service, and can't easily & accurately be mocked.
Note: In my example, I'm using EF5.
First, I have a service method for creating a user:
void CreateUser(string username, string password);
My test assembly has a SetUpFixture (one-time for test run) that creates of my database (EF Code First) and test data:
[SetUpFixture]
public class SetUpFixture
{
[SetUp]
public void SetUp()
{
using (var context = new MyDbContext())
{
Database.SetInitializer(new DropCreateDatabaseAlways<MyDbContext>());
// Set up a bunch of initial data and commit
}
}
}
Then before each test, my TestFixtureSetup method runs that creates an instance of my DB context, which is set to rollback when it's disposed (after each test), and also creates the instance of my service:
[TestFixtureSetUp]
public virtual void TestFixtureSetUp()
{
_context = new MyContext(rollbackOnDispose: true);
UserService = new SignupService(_context);
}
[TestFixtureTearDown]
public virtual void TestFixtureTearDown()
{
Context.Dispose();
}
Finally, my actual integration test to make sure that what valid data is passed in, a record with my username got created (and here's where my problem lies):
[Test]
public void ValidDataShouldResultInNewRecordWithUsername()
{
SignupService.CreateUser("myuser", "fakepassword");
var q = from user in Context.Users
where user.Username == "myuser"
select user;
var actualUser = q.Single();
Assert.AreEqual("myuser", actualUser.Username);
}
Here are my questions:
1) First of all, is this even the way to go testing services dependent on EF? I know there are several approaches, I just want to make sure there's nothing crazy with this approach.
2) Second, how should I verify the service method (CreateUser) did what it was supposed to do, before the data is committed (which I don't want it to commit, so that my database state remains as it was initialized prior to each test)? The query in the test above returns no data, since it wasn't committed yet.