Nesting test runners - unit-testing

I am trying to find out whether and how it is possible to nest JUnit test runners, e.g. combine a GuiceJUnitRunner, a Parameterized and a HierarchicalcontextRunner.
To me, it seems that JUnit was not designed to achieve this easily, otherwise BlockJUnit4ClassRunner should have a method which passes the next Runner as an argument.
Someone also implemented a ParallelParameterized runner, which looks to me like combining Parallel and Parameterized was not easily possible.
When googling for "nested" and "JUnit", it comes up with lots of information for nested classes, but I'm looking for nesting Runners, not classes.

There is something called NestedRunner for running plain old Java classes in nested configuration.
your test starts with #RunWith(NestedRunner.class) and here is the example that I found:
#RunWith(NestedRunner.class)
public class ListTest {
// inner class for sharing common context
public class WithArrayList {
// some context for these tests
ArrayList<String> list = new ArrayList<String>();
public class WhenEmpty {
#Test
public void itIsEmpty() {
assertTrue(list.isEmpty());
}
public class AfterAddingAnElement {
// some more context for these tests
String element = "Element";
// you can use instance initializer to initialize your context
// it will be run once per test
{
// the list is still empty in here
assertTrue(list.isEmpty());
list.add(element);
}
#Test
public void itIsNotEmpty() {
assertFalse(list.isEmpty());
}
#Test
public void itContainsTheElement() {
assertTrue(list.contains(element));
}
#Test
public void addingAnotherElementIncreasesSize() {
int sizeBeforeAdding = list.size();
list.add("AnotherElement");
assertThat(list.size(), is(greaterThan(sizeBeforeAdding)));
}
#Test
public void listSizeIsStillOne() {
assertThat(list.size(), is(equalTo(1)));
}
}
#Test
public void isStillEmpty() {
assertTrue(list.isEmpty());
}
}
public class WithTwoElements {
#Before
public void init() {
list.add("Element1");
list.add("Element2");
}
#Test
public void hasSizeOfTwo() {
assertThat(list.size(), is(equalTo(2)));
}
}
}
}
and here is the source for further info

Related

Mockito- thenReturn(true) still returns false on a mock object

I recently started reading up about Mockito. The following line of code must return true as per my understanding, but it returns false.
Test Class
public class PersonServiceImplTest {
Car car;
#InjectMocks
CarServiceImpl carService;
#Mock
CarDAOImpl carDAO;
#Before
public void setUp() {
MockitoAnnotations.initMocks(this);
}
#Test
public void testUpdateCar() {
int carId = 1;
Mockito.when(carDAO.getCarById(any(Integer.class))).thenReturn(new Car());
carService.updateCar(carId);
Mockito.when(carDAO.isLicenseExpired(any(Car.class))).thenReturn(true);
Mockito.verify(carDAO).updateCar(any(Car.class));
Mockito.verify(carDAO, times(1)).isLicenseExpired(any(Car.class));
Mockito.verify(carDAO, times(1)).issueLicense(any(Car.class));
}
}
Class to be tested
public class CarServiceImpl implements CarService {
#Autowired carDAO carDAO;
#Override
public Response updateCar(int carId) {
Car car =carDAO.getCarById(carId);
try {
carDAO.updateCar(car);
if(carDAO.isLicenseExpired(car)))
carDAO.issueLicense(car);
} catch (Exception e) {
log.error(e.getMessage());
return Response.status(Status.INTERNAL_SERVER_ERROR).build();
}
return Response.ok(Status.CREATED).build();
}
CarDAOImpl deals with the database, if needed, will update that too.
Thanks in advance.
These two lines are ordered incorrectly:
carService.updateCar(carId);
Mockito.when(carDAO.isLicenseExpired(Mockito.any(Car.class))).thenReturn(true);
The first line in that pair invokes the class-under-test and the second line sets up an expectation of how your carDAO should behave inside the class-under-test. So, you are setting the expectation after you invoke the class-under-test.
The following test will pass:
#Test
public void testUpdateCar() {
int carId = 1;
// establish expectations of how carDAO should behave inside updateCar()
Mockito.when(carDAO.getCarById(Mockito.any(Integer.class))).thenReturn(new Car());
Mockito.when(carDAO.isLicenseExpired(Mockito.any(Car.class))).thenReturn(true);
// invoke the class-under-test
carService.updateCar(carId);
// verify that CarService used CarDAO correctly
Mockito.verify(carDAO).updateCar(Mockito.any(Car.class));
Mockito.verify(carDAO).isLicenseExpired(Mockito.any(Car.class));
Mockito.verify(carDAO).issueLicense(Mockito.any(Car.class));
}

Nhibernate unit testing. Child class cannot use Base class property

I am using Fluent NHibernate and trying to do unit testing. Now I have a base test class which looks as follows:
[TestClass]
public abstract class BaseTest<TEntity> where TEntity : IBaseModel
{
private const string testDbFile = "test.db";
private static ISessionFactory sessionFactory;
protected static ISession session;
[TestMethod]
public void configureDB()
{
try
{
if (sessionFactory == null)
{
sessionFactory = Fluently.Configure()
.Database(SQLiteConfiguration.Standard
.UsingFile(testDbFile))
.Mappings(m => m.FluentMappings.AddFromAssemblyOf<AdminTest>())
.ExposeConfiguration(BuildSchema)
.BuildSessionFactory();
}
}
catch (Exception ex)
{
Console.WriteLine(ex.InnerException.Message);
}
}
private static void BuildSchema(Configuration config)
{
new SchemaUpdate(config).Execute(false, true);
}
[TestMethod]
public void sessionCreated()
{
session = sessionFactory.OpenSession();
}
[TestMethod]
public virtual void AddEntity_EntityWasAdded()
{
var entity = BuildEntity();
InsertEntity(entity);
session.Evict(entity);
var reloadedEntity = session.Get<TEntity>(entity.Id);
Assert.IsNotNull(reloadedEntity);
AssertAreEqual(entity, reloadedEntity);
AssertValidId(reloadedEntity);
}
There are also other methods which update and delete an entity. And I have AdminTest class which inherits BaseTest. In AdminTest I have following method:
[TestClass]
public class AdminTest : BaseTest<Admin>
{
[TestMethod]
public void SelectWorks()
{
IList<Admin> admins = session.QueryOver<Admin>().List();
Assert.AreNotEqual(0, admins.Count);
}
}
Here I always have exception, because session is null. Maybe I am wrong in the way of thinking how visual studio performs unit tests (I am newbie in it)?
Now I think like that, visual studio works in the following way
runs test-methods from BaseTest (there it configures database and creates session)
runs selectWorks method. Here I was thinking it should use session from BaseTest
Could you explain what is wrong in my way of thinking? And I want to be able to query from child classes, what is the right way of doing it?
Thanks, any help is appreciated, .
I would suggest using [TestInitialize] and [TestCleanup] in your abstract base class and doing something like the following:
[TestInitialize]
public void TestInitialize()
{
Console.Out.WriteLine("Get a ISession object");
}
[TestCleanup]
public void TestCleanup()
{
Console.Out.WriteLine("Dispose ISession");
}
Then in your child classes continue to do what you are doing:
[TestMethod]
public void DoDbWork()
{
Console.Out.WriteLine("Running a query via nhibernate");
}
You really just want to ensure you have a clean session for each test. The attributes for TestInitialize and TestCleanup will run before and after each unit test. Here is the documentation for those attributes.
To ensure your ISession is in the right state,follow something like this.

Cannot seem to moq EF CodeFirst 4.1.Help anyone?

I have been given the task to evaluate codeFirst and possible to use for all our future projects.
The evaluation is based on using codeFirst with an existing database.
Wondering if it's possible to mock the repository using codeFirst 4.1.(no fakes)
The idea is to inject a repository into a service and moq the repository.
I have been looking on the net but I have only found an example using fakes.I dont want to use fakes I want to use moq.
I think my problem is in the architecture of the DAL.(I would like to use unitOfWork etc.. by I need to show a working moq example)
Below is my attempt(Failed miserably) due to lack of knowledge on Code first 4.1.
I have also uploaded a solution just in case somebody is in good mood and would like to change it.
http://cid-9db5ae91a2948485.office.live.com/browse.aspx/Public%20Folder?uc=1
I am open to suggestions and total modification to my Dal.Ideally using Unity etc.. but I will worry about later.
Most importantly I need to be able to mock it. Without ability to use MOQ we will bin the project using EF 4.1
Failed attempt
//CodeFirst.Tests Project
[TestClass]
public class StudentTests
{
[TestMethod]
public void Should_be_able_to_verify_that_get_all_has_been_called()
{
//todo redo test once i can make a simple one work
//Arrange
var repository = new Mock<IStudentRepository>();
var expectedStudents = new List<Student>();
repository.Setup(x => x.GetAll()).Returns(expectedStudents);
//act
var studentService = new StudentService(repository.Object);
studentService.GetAll();
//assert
repository.Verify(x => x.GetAll(), Times.AtLeastOnce());
}
}
//CodeFirst.Common Project
public class Student
{
public int StudentId { get; set; }
public string Name { get; set; }
public string Surname { get; set; }
}
public interface IStudentService
{
IEnumerable<Student> GetAll();
}
//CodeFirst.Service Project
public class StudentService:IStudentService
{
private IStudentRepository _studentRepository;
public StudentService()
{
}
public StudentService(IStudentRepository studentRepository)
{
_studentRepository = studentRepository;
}
public IEnumerable<Student> GetAll()
{
//TODO when mocking using moq this will actually call the db as we need a separate class.
using (var ctx = new SchoolContext("SchoolDB"))
{
_studentRepository = new StudentRepository(ctx);
var students = _studentRepository.GetAll().ToList();
return students;
}
}
}
//CodeFirst.Dal Project
public interface IRepository<T> where T : class
{
T GetOne(Expression<Func<T, bool>> predicate);
IEnumerable<T> GetAll();
IEnumerable<T> Find(Expression<Func<T, bool>> predicate);
void Add(T entity);
void Delete(T entity);
T Single(Func<T, bool> predicate);
T First(Func<T, bool> predicate);
}
public class RepositoryBase<T> : IRepository<T> where T : class
{
private readonly IDbSet<T> _dbSet;
public RepositoryBase(DbContext dbContext)
{
_dbSet = dbContext.Set<T>();
if (_dbSet == null) throw new InvalidOperationException("Cannot create dbSet ");
}
protected virtual IDbSet<T> Query
{
get { return _dbSet; }
}
public T GetOne(Expression<Func<T, bool>> predicate)
{
return Query.Where(predicate).FirstOrDefault();
}
public IEnumerable<T> GetAll()
{
return Query.ToArray();
}
public IEnumerable<T> Find(Expression<Func<T, bool>> predicate)
{
return Query.Where(predicate).ToArray();
}
public void Add(T entity)
{
_dbSet.Add(entity);
}
public void Delete(T entity)
{
_dbSet.Remove(entity);
}
public T Single(Func<T, bool> predicate)
{
return Query.Where(predicate).SingleOrDefault();
}
public T First(Func<T, bool> predicate)
{
return Query.Where(predicate).FirstOrDefault();
}
}
public class SchoolContext:DbContext
{
public SchoolContext(string connectionString):base(connectionString)
{
Database.SetInitializer<SchoolContext>(null);
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
//Not sure why I have to do this.Without this when using integration testing
//as opposed to UnitTests it does not work.
modelBuilder.Entity<Student>().ToTable("Student"); }
public DbSet<Student> Students { get; set; }
}
public interface IStudentRepository:IRepository<Student>
{
}
public class StudentRepository : RepositoryBase<Student>, IStudentRepository
{
public StudentRepository(DbContext dbContext)
: base(dbContext)
{
}
public IEnumerable<Student> GetStudents()
{
return GetAll();
}
}
Again feel free to modify or whatever is needed to help me to get something together.
Thanks a lot for your help
When I started with repository and unit of work patterns I used the implementation similar to this (it is for ObjectContext API but converting it to DbContext API is simple). We used that implementation with MOQ and Unity without any problems. By the time implementations of repository and unit of work have evolve as well as the approach of injecting. Later on we found that whole this approach has serious pitfalls but that was alredy discussed in other questions I referenced here (I highly recommend you to go through these links).
It is very surprising that you are evaluating the EFv4.1 with high emphasis on mocking and unit testing and in the same time you defined service method which is not unit-testable (with mocking) at all. The main problem of you service method is that you are not passing repository/context as dependency and because of that you can't mock it. The only way to test your service and don't use the real repository is using some very advanced approach = replacing mocking and MOQ with detouring (for example Moles framework).
First what you must do is replacing your service code with:
public class StudentService : IStudentService
{
private readonly IStudentRepository _studentRepository;
public StudentService(IStudentRepository studentRepository)
{
_studentRepository = studentRepository;
}
public IEnumerable<Student> GetAll()
{
return _studentRepository.GetAll().ToList();
}
}
Btw. this is absolutely useless code and example of silly layering which doesn't offer any useful functionality. Just wrapping the call to repository only shows that service is not needed at all as well as unit testing this method is not needed. The main point here is integration test for GetAll method.
Anyway if you want to unit thest such method with MOQ you will do:
[TestClass]
public class StudentsServiveTest
{
private Mock<IRespository<Student>> _repo;
[TestInitialize]
public void Init()
{
_repo = new Mock<IRepository<Student>>();
_repo.Setup(r => r.GetAll()).Returns(() => new Student[]
{
new Student { StudentId = 1, Name = "A", Surname = "B" },
new Student { StudentId = 2, Name = "B", Surname = "C" }
});
}
[TestMethod]
public void ShouldReturnAllStudents()
{
var service = new StudentsService(_repo.Object);
var data = service.GetAll();
_repo.Verify(r => r.GetAll(), Times.Once());
Assert.IsNotNull(data);
Assert.AreEqual(2, data.Count);
}
}
The issue from what I can see is that you are throwing away the mock object and newing up a new instance
_studentRepository = new StudentRepository(ctx);
Perhaps add a method on the interface to add the context object and reuse the same instance that was injected in the constructor.
using (var ctx = new SchoolContext("SchoolDB"))
{
_studentRepository.Context = ctx;
var students = _studentRepository.GetAll().ToList();
return students;
}
}

Using inheritance in MSTest

I am setting up some MSTest based unit tests. To make my life easier I want to use a base class that handles the generic setup and taredown all of my tests require. My base class looks like this:
[TestClass]
public class DBTestBase {
public TestContext TestContext { get; set; }
[ClassInitialize()]
public static void MyClassInitialize(TestContext testContext) {
var config = new XmlConfigurationSource("ARconfig_test.xml");
ActiveRecordStarter.Initialize(Assembly.Load("LocalModels"), config);
}
[TestInitialize()]
public void MyTestInitialize() {
ActiveRecordStarter.CreateSchema();
Before_each_test();
}
protected virtual void Before_each_test() { }
[TestCleanup()]
public void MyTestCleanup() {
After_each_test();
}
protected virtual void After_each_test() { }
}
My actual test class looks like this:
[TestClass]
public class question_tests : DBTestBase {
private void CreateInitialData() {
var question = new Question()
{
Name = "Test Question",
Description = "This is a simple test question"
};
question.Create();
}
protected override void Before_each_test() {
base.Before_each_test();
CreateInitialData();
}
[TestMethod]
public void test_fetching() {
var q = Question.FindAll();
Assert.AreEqual("Test Question", q[0].Name, "Incorrect name.");
}
}
The TestInitialize function works as expected. But the ClassInitialize function never runs. It does run if I add the following to my child class:
[ClassInitialize()]
public static void t(TestContext testContext) {
MyClassInitialize(testContext);
}
Is it possible to get my base class initialize function to run without referencing it in my child class?
ClassInitialize method is executed if and only if the concerned "class" contains at least one TestMethod, and at least one TestMethod from the class is selected for execution.
Confirm this was a problem for me too. I used a constructor on the base and a destructor for the cleanup
[TestClass]
public class question_tests : DBTestBase {
...
[TestCleanup()]
public void TestCleanup()
{
base.MyTestCleanup();
}

NUnit Conditional Teardown?

Is there a way to do a conditional TearDown in NUnit?
I have a TestFixture which has a need to run cleanup code for just a few tests, and I don't really want to:
Run the TearDown method on every test
Create a private helper method and call it from the tests requiring cleanup if I can avoid it
There isn't unfortunately.
Can you not do the cleanup in the [TestFixtureTearDown] instead, so once all the tests have finished? I guess that depends on whether the cleanup has to be done before the next test runs.
Alternatively, put those tests that require a cleanup in another class/TextFixture together, away from the other tests. Then you can use a TearDown in there which doesn't need to be conditional.
Edit:
One thing I've just thought of, which could be done to achieve the aim though probably isn't actually worth it for this particular need, is that you can extend NUnit - create your own custom attributes which you could handle however you wanted. This is mentioned here. Like I say, I don't think really you should go down that route for this, but is useful to know none-the-less
You can have the main TearDown in a base class:
[TearDown]
public virtual void TearDown()
{
// Tear down things here
}
and then override it in the class where you have the tests that should not run the tear down code:
[TearDown]
public override void TearDown()
{
// By not calling base.TearDown() here you avoid tearing down
}
Extend all you classes with test from BaseTest
public class BaseTest
{
[SetUp]
public void BeforeTest()
{
GetService<NUnitHooksController>().ExecuteBeforeTestHooks(this);
}
[TearDown]
public void AfterTest()
{
GetService<NUnitHooksController>().ExecuteAfterTestHooks(this);
}
}
Use AfterTest and BeforeTest hooks. Works both with and without category.
public class ExampleTest : BaseTest
{
[Test, Category("asdasd")]
public void Test01()
{
...
}
[AfterTest("asdasd")]
public void ExampleHook()
{
...
}
}
public class NUnitHooksController
{
private readonly ILogger _log;
public NUnitHooksController(ILogger log)
{
_log = log;
}
public void ExecuteBeforeTestHooks(object testClass)
{
ExecuteHooks(testClass, typeof(BeforeTestAttribute));
}
public void ExecuteAfterTestHooks(object testClass)
{
ExecuteHooks(testClass, typeof(AfterTestAttribute));
}
private MethodInfo[] GetHookMethods(object currentTestClass, Type attributeType)
{
return currentTestClass
.GetType()
.GetMethods()
.Where(m => m.GetCustomAttributes(attributeType, false).Length > 0)
.ToArray();
}
private void ExecuteHooks(object testClass, Type requiredAttributeType)
{
var hooks = GetHookMethods(testClass, requiredAttributeType);
var testCategories = GetTestCategories();
foreach (var hook in hooks)
{
var allAttributes = hook.GetCustomAttributes(requiredAttributeType, true);
foreach (var attribute in allAttributes)
{
if (!attribute.GetType().IsEquivalentTo(requiredAttributeType))
{
continue;
}
var hookCategories = GetCategoriesFromAttribute(attribute);
// if we do not have specific category on hook
// or we have at least one same category on hook and test
if (!hookCategories.Any() || hookCategories.Intersect(testCategories).Any())
{
ExecuteHookMethod(testClass, hook);
}
}
}
}
private object[] GetTestCategories()
{
return TestContext.CurrentContext.Test.Properties["Category"].ToArray();
}
private void ExecuteHookMethod(object testClass, MethodInfo method)
{
var hookName = method.Name;
_log.Information($"Executing - '{hookName}' hook");
try
{
method.Invoke(testClass, Array.Empty<object>());
}
catch (Exception e)
{
_log.Error($"Executing of - '{hookName}' hook failed - {e}");
}
}
private string[] GetCategoriesFromAttribute(object attribute)
{
if (attribute is BeforeTestAttribute beforeTestAttribute)
{
return beforeTestAttribute.Categories;
}
if (attribute is AfterTestAttribute afterTestAttribute)
{
return afterTestAttribute.Categories;
}
throw new ArgumentException($"{attribute.GetType().FullName} - does not have categories");
}
}
I have solved this using the name of the test:
namespace TestProject
{
public class TestClass
{
// Test without TearDown
[Test]
public void Test1()
{
Assert.Pass("Test1 passed");
}
// Test with TearDown
[Test]
public void Test2()
{
Assert.Pass("Test2 passed");
}
[TearDown]
public void TearDown()
{
// Execute only after Test2
if (TestContext.CurrentContext.Test.Name.Equals(nameof(this.Test2)))
{
// Execute Test2 TearDown...
}
}
}
}
Or if you want to use the full name of Test2 (TestProject.TestClass.Test2) you can replace the line
if (TestContext.CurrentContext.Test.Name.Equals(nameof(this.Test2)))
by
if (TestContext.CurrentContext.Test.FullName.Equals(typeof(TestClass).FullName + "." nameof(this.Test2)))