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.
Related
I am using Mockito to write a simple unit test. I have a smiple abstract class which implements Runnable:
public abstract class MyRunnable implements Runnable {
#Override
public void run() {
doTask();
}
public abstract void doTask();
}
Then, a function under test uses MyRunnable:
public class MyService {
public void something() {
executor.execute(new MyRunnable() {
#Override
doTask() {
…
}
});
}
}
My test case, I want to test doTask() has run :
#Test
public void testSomething() {
…
ArgumentCaptor<MyRunnable> myCaptor = ArgumentCaptor.forClass(MyRunnable.class);
verify(mockMyService).something(myCaptor.capture());
// get what has been captured
MyRunnable myRunnable = myCaptor.getValue();
//verify doTask() has run , but got ERROR.
verify(myRunnable).doTask();
}
My test case throw the following error:
org.mockito.exceptions.misusing.NotAMockException:
Argument passed to verify() is of type and is not a mock!
The error complains that verify() only accept mocked object. Then, how can I verify/test that the captured MyRunnable object has run doTask() with Mockito?
If you have control over your codebase, you can make your code testable with Mockito by moving any code that uses the new keyword into a separate Factory class like so...
public class MyService {
private MyRunnableFactory = factory;
public MyService(MyRunnableFactory factory) {
this.factory = factory;
}
public void something() {
executor.execute(factory.createInstance());
}
}
Then your test can simply inject a Mock of the factory which you can verify its behaviour/interactions
#Mock MyRunnableFactory factory;
#Mock MyRunnable myRunnable;
#Test
public void testSomething() {
when(factory.createInstance()).thenReturn(myRunnable);
// method under test
MyService service = new MyService();
service.something();
verify(myRunnable).doTask();
}
I use a rule of thumb that classes that creates objects, shouldn't have any business logic, so you don't have these testing headaches. This is essentially the Single Responsibilty Principal
You can't do this with Mockito because MyRunnable is created by the code under test. But you may have a look at PowerMock because it allows you to mock the constructor: https://github.com/jayway/powermock/wiki/MockConstructor
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
I am using TestNG 6.8.8, Mockito 1.9.5 and PowerMock 1.5.4. When I mock a final void method, the test passes sometimes and fails sometimes with error UnfinishedStubbingException.
Is this a PowerMock bug?
public abstract class Parent implements Serializable {
protected abstract void validate();
public final void validateSomething() {
// some code here
}
}
#PrepareForTest({ Parent.class })
public class ParentTest {
#Test
public final void testSomeMethod() {
Parent parentObj = PowerMockito.mock(Parent.class);
doNothing().when(parentObj).validateSomething();
TestCodeThatResultsInCallToParentObj.validateSomething();
}
}
Error message:
org.mockito.exceptions.misusing.UnfinishedStubbingException:
Unfinished stubbing detected here:
-> at org.powermock.api.mockito.internal.PowerMockitoCore.doAnswer(PowerMockitoCore.java:36)
E.g. thenReturn() may be missing.
Examples of correct stubbing:
when(mock.isOk()).thenReturn(true);
when(mock.isOk()).thenThrow(exception);
doThrow(exception).when(mock).someVoidMethod();
Hints:
1. missing thenReturn()
2. you are trying to stub a final method, you naughty developer!
at org.powermock.api.mockito.internal.invocation.MockitoMethodInvocationControl.performIntercept(MockitoMethodInvocationControl.java:260)
You can use delegation and wrap the execution of that class in your class.
class ParentWrapper {
private final Parent delegate;
ParentWrapper(Parent delegate) {
this.delegate = delegate;
}
void validateSth() {
delegate.validateSth();
}
}
and now you can mock the ParentWrapper without any Powermock.
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;
}
}
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();
}