1
\$\begingroup\$

I've created unit test for the "student" CRUD operations that looks like this:

[Test]
 public void Can_Exec_CrudOps()
 {
 #region Prepare
 var account = Processor.Execute(new CreateAccount
 {
 Email = "[email protected]",
 Username = "username",
 Password = "password",
 }).Result;
 #endregion
 var student = Processor.Execute(new CreateStudent
 {
 AccountId = account.EntityID
 }).Result;
 Assert.NotNull(student);
 student.AreEqual(Processor.Execute(new GetStudent
 {
 EntityId = student.EntityID
 }).Result);
 student.AreEqual(Processor.Execute(new GetStudentByAccount
 {
 AccountId = account.EntityID
 }).Result);
 var upd_student = Processor.Execute(new UpdateStudent
 {
 EntityId = student.EntityID,
 Flags = StudentFlags.Active
 }).Result;
 Assert.NotNull(upd_student);
 upd_student.AreEqual(student);
 upd_student.Flags.AreEqual(StudentFlags.Active);
 Processor.Execute(new DeleteStudent
 {
 EntityId = student.EntityID
 });
 }

As you can see, the region #prepare contains code that will insert required data to the database for the current test to be possible.

Is it good practice to create a single test for each CRUD operation and then call that test inside the tests that require them?

What I'm thinking about would look like this:

 [TestFixture]
public class StudentTest : OperationTest
{
 protected override IEnumerable<Type> ModelMappings
 {
 get
 {
 return NHMappings.EDUCATION;
 }
 }
 [Test]
 public void Can_Exec_CrudOps()
 {
 #region Prepare
 // here is what changed //
 var acc = new AccountTests();
 var acc_id= acc.create_account();
 #endregion
 var student = Processor.Execute(new CreateStudent
 {
 //here too//
 AccountId = acc_id
 }).Result;
 Assert.NotNull(student);
 student.AreEqual(Processor.Execute(new GetStudent
 {
 EntityId = student.EntityID
 }).Result);
 student.AreEqual(Processor.Execute(new GetStudentByAccount
 {
 // and here//
 AccountId = acc_id
 }).Result);
 var upd_student = Processor.Execute(new UpdateStudent
 {
 EntityId = student.EntityID,
 Flags = StudentFlags.Active
 }).Result;
 Assert.NotNull(upd_student);
 upd_student.AreEqual(student);
 upd_student.Flags.AreEqual(StudentFlags.Active);
 Processor.Execute(new DeleteStudent
 {
 EntityId = student.EntityID
 });
 // and here //
 acc.deleteaccount(acc_id);
 }
}

So the point is not to write the same code over and over again.

Jamal
35.2k13 gold badges134 silver badges238 bronze badges
asked Dec 17, 2013 at 11:44
\$\endgroup\$
1
  • 2
    \$\begingroup\$ Please include a language tag next time, since this looks like C#, I added that tag. \$\endgroup\$ Commented Dec 17, 2013 at 13:28

1 Answer 1

6
\$\begingroup\$

No, I would say, and the reason for that is that you have too many asserts in your test (it does to many thinks). There should only be one reason for a test to fail. So:

Split your test into smaller ones with a more descriptive name and stick to one assert per test. By doing so it's also easier to track down why a test is failing, both in the case is the bug is in the test or in the production code.

answered Dec 17, 2013 at 20:27
\$\endgroup\$
1
  • 1
    \$\begingroup\$ I would also call these integration tests because they are hitting the database. Unit tests are written to test a very specific section of the logic. \$\endgroup\$ Commented Dec 17, 2013 at 20:48

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.