How do i make Base class with [TestClass()], where i will do MyClassInitialize(), and after that, i will just make my another Test classes just like that - MyNewTest : BaseTest
and there will no initializing?
(using MSTest)
The ClassInitialize won’t work on a base class. It seems that this attribute is searched for only on the executed test class. However, you can call the base class explicitly.
Here is an example:
[TestClass]
public class MyTestClass : TestBase
{
[TestMethod]
public void MyTestMethod()
{
System.Diagnostics.Debug.WriteLine("MyTestMethod");
}
[ClassInitialize]
public new static void MyClassInitialize(TestContext context)
{
TestBase.MyClassInitialize(context);
}
}
[TestClass]
public abstract class TestBase
{
public TestContext TestContext { get; set; }
public static void MyClassInitialize(TestContext context)
{
System.Diagnostics.Debug.WriteLine("MyClassInitialize");
}
[AssemblyInitialize]
public static void AssemblyInit(TestContext context)
{
}
}
In NUnit/MbUnit you simply put the Initalize/Cleanup methods with the respective attributes in the base class, then inherit from it.
I haven't tried this yet with MSTest, but I wouldn't recommend this framework anyway.
Thomas
Related
There is a Adapter class which calls another legacyService and legacyService calls legacyDao and I want to mock the Legacy service calls.
In the below code SomeBean is returned as null instead of one the one that i created and passed in thenReturn. What could be the issue here?Please help I am new to mocking framework.
public class AdapterImpl implements Adpater{
//Injected through setter or constructor injection
private LegacyService legacy;
public SomeBean myMethod(){
CommonUtils.someStaticMethod()
return legacy.legacyService();
}
}
public class LegacyServiceImpl implements LegacyService{
//Injected through setter or constructor injection
private LegacyDAO ldao;//LegacyDAO is an interface
public SomeBean legacyService(){
return ldao.legacyDAO();
}
}
Test class
#RunWith(PowerMockRunner.class)
#PrepareForTest({CommonUtils.class})
public class AdapterImplTest{
#Mock private LegacyServiceImpl legacyService;
private LegacyDAO legacyDAO;
#Before
public void before(){
MockitoAnnotations.initMocks(this);
}
#Test
public void myMethodTest(){
PowerMockito.mockStatic(CommonUtils.class);
PowerMockito.when(CommonUtils.someStaticMethod()).thenReturn(someString());
legacyDAO = PowerMockito.mock(LegacyDAO.class);
SomeBean bean = new SomeBean(sometring1,somestring2);
PowerMockito.when(legacyDAO.legacyDAO().thenReturn(bean);//I am mocking interface method implementation
legacyService.setLegacyDAO(legacyDAO);
PowerMockito.when(legacyService.legacyService().thenReturn(bean);//same bean as above
AdapterImpl impl = new AdapterImpl();
impl.setLegacyService(legacyService)
//Below method call is not returning the bean that I constructed above it is being returned as null
impl.myMethod();
}
}
The original code posted in the question has many typos like missing parentheses and semi-colons. When I correct them, and fill in some of the methods like AdapterImpl.setLegacyService(), the test passes.
Then, as suggested in my comment, I removed the mocking of LegacyDAO. That mock object should not be needed if LegacyServiceImpl.legacyService() is properly mocked. When I rerun the test, it again passes.
All of which leads me to believe that there is an issue with the injection of the mock LegacyService object into AdapterImpl
FYI here is my passing test code, showing my typo fixes and assumptions about methods not shown in the original question. Hope this helps!
#RunWith(PowerMockRunner.class)
#PrepareForTest({ AdapterImplTest.CommonUtils.class })
public class AdapterImplTest {
#Mock
private LegacyServiceImpl legacyService;
// private LegacyDAO legacyDAO; // removed, no need to mock
#Before
public void before() {
MockitoAnnotations.initMocks(this);
}
#Test
public void myMethodTest() {
PowerMockito.mockStatic(CommonUtils.class);
PowerMockito.when(CommonUtils.someStaticMethod()).thenReturn(someString());
// legacyDAO = PowerMockito.mock(LegacyDAO.class);
SomeBean bean = new SomeBean("sometring1", "somestring2");
// I am mocking interface method implementation
// PowerMockito.when(legacyDAO.legacyDAO()).thenReturn(bean);
// legacyService.setLegacyDAO(legacyDAO);
// same bean as above
PowerMockito.when(legacyService.legacyService()).thenReturn(bean);
AdapterImpl impl = new AdapterImpl();
impl.setLegacyService(legacyService);
// Below method call is not returning the bean that I constructed above
// it is being returned as null
impl.myMethod();
}
private String someString() {
return "hello";
}
public class SomeBean {
public SomeBean(String string, String string2) {
}
}
public interface LegacyService {
public SomeBean legacyService();
}
public interface Adpater {
}
public class AdapterImpl implements Adpater {
// Injected through setter or constructor injection
private LegacyService legacy;
public SomeBean myMethod() {
CommonUtils.someStaticMethod();
return legacy.legacyService();
}
public void setLegacyService(LegacyServiceImpl legacyService) {
legacy = legacyService;
}
}
public class LegacyServiceImpl implements LegacyService {
// Injected through setter or constructor injection
private LegacyDAO ldao;// LegacyDAO is an interface
public SomeBean legacyService() {
return ldao.legacyDAO();
}
public void setLegacyDAO(LegacyDAO legacyDAO) {
ldao = legacyDAO;
}
}
public class LegacyDAO {
public SomeBean legacyDAO() {
return null;
}
}
public static class CommonUtils {
public static String someStaticMethod() {
return "in CommonUtils.someStaticMethod()";
}
}
}
So i have a class that needs to be tested. Lets call it ClassToTest. It has a couple of Dao objects as fields.
Public class ClassToTest {
#Autowired
MyDao dao;
void methodToTest() {
dao.save(something);
}
}
As you can see ClassToTest does not contain any constructor or setter and I am using spring to autowire the fields.
Now, I have a base test class with all the dependencies that classToTest requires:
public abstract BaseTest {
#Mock
MyDao dao;
}
And the testClass extends this BaseTest class :
public class TestClass extends BaseTest {
#InjectMocks
ClassToTest classToTest = new ClassToTest();
#Before
public void setup() {
MockitoAnnotations.initMocks(this);
}
#Test
public void test() {
classToTest.methodToTest();
}
}
This results in a null pointer exception when the save happens. However, if i change setup method to this :
#Before
public void setup() {
MockitoAnnotations.initMocks(this);
classToTest.dao = dao;
}
the test passes.
My understanding was that when a class does not have a constructor or a setter, InjectMocks would inject the mocks by using field injection. Why is that not happening here?
Figured out that this is a bug in the 1.8.5 version that i was using : https://code.google.com/p/mockito/issues/detail?id=229.
Upgrading 1.10 fixed the issue.
When running multiple [TestClass]es at the same time, why do the [ClassCleanup()] methods only get called at the very end?
File: UnitTest1.cs
[TestClass]
public class UnitTest1
{
[ClassInitialize()]
public static void ClassInit(TestContext context)
{
}
[ClassCleanup()]
public static void ClassCleanup()
{
}
[TestMethod]
public void TestMethod1()
{
}
}
File: UnitTest2.cs
[TestClass]
public class UnitTest2
{
[ClassInitialize()]
public static void ClassInit(TestContext context)
{
}
[ClassCleanup()]
public static void ClassCleanup()
{
}
[TestMethod]
public void TestMethod1()
{
}
}
The execution order is the following:
UnitTest2.ClassInit()
UnitTest2.TestMethod1()
UnitTest1.ClassInit()
UnitTest1.TestMethod1()
UnitTest2.ClassCleanup()
UnitTest1.ClassCleanup()
Notice that both [ClassCleanup] methods are executed at the end of the set; not after each TestClass is "done".
But I expected a different behavior:
UnitTest2.ClassInit()
UnitTest2.TestMethod1()
UnitTest2.ClassCleanup() - Expected
UnitTest1.ClassInit()
UnitTest1.TestMethod1()
UnitTest1.ClassCleanup() - Expected
Microsoft's Documentation - ClassCleanupAttribute Class says, "Identifies a method that contains code to be used after all the tests in the test class have run and to free resources obtained by the test class. "
But it appears to be run/executed late!
How do I fix this? Or find a way to execute a method from the same TestClass right before the next ClassInitialize method.
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.
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();
}