How to get test result status from MSTest? - unit-testing

In NUnit, I can get the test result from context.Result.State. If its NUnit.Framework.TestState.Success, then I know the test passed.
In MSTest, how do I get that info?
I saw context.Properties.Keys, but none of them speak of the status of the test result.

Use the TestContext.CurrentTestOutcome property in the TestCleanup method:
[TestClass]
public class UnitTest
{
private TestContext TestContext { get; set; }
[TestCleanup]
public void TestCleanup()
{
if (TestContext.CurrentTestOutcome == UnitTestOutcome.Passed)
//do something
}
[TestMethod]
public void TestMethod()
{
}
}

Related

TestContext property is null

i have been tryign to get current test directory from where tests are running.
code that i m using
[TestFixture]
public class ValidatePDF
{
public NUnit.Framework.TestContext TestContext { get; set; }
[SetUp]
public void Init()
{
string t = TestContext.TestDirectory;
}
}
TestContext is always null.
i m using Visual Studio 2017 , and NUnit 3
i have tried with MS TextContext but it always return null
public Microsoft.VisualStudio.TestTools.UnitTesting.TestContext TestContext { get; set; }
[Test]
public void GetMetaInfo()
{
string t = TestContext.TestDir;
}
Remove the MS TestContext, and use NUnit's built in TestContext. Note that it is a static property, so access the CurrentContext's members.

Shared Preferences is null in mockito

I am trying to mock a simple shared preferences using Mockito . Since, the examples on google are too complicated to make anything out of it, I decided to go ahead on my own.
The shared preferences are setup using dagger.
It crashes with NPE in the saveString method in the SharedPreferenceManager class on the putString line.
#Module
public class StudentModule {
#Provides
#Singleton
static Context getContext(Application application) {
return application.getApplicationContext();
}
#Provides
#Singleton
static SharedPreferences getSharedPreferences(Context context) {
return PreferenceManager.getDefaultSharedPreferences(context);
}
}
There is a manager class:
public class SharedPreferenceManager {
private SharedPreferences sharedPreferences;
private Context context;
#Inject public SharedPreferenceManager(SharedPreferences sharedPreferences, Context context){
this.sharedPreferences=sharedPreferences;
this.context=context;
}
public String doSomething(){
return sharedPreferences.getString("s","");
}
public void saveString(String s){
System.out.println(sharedPreferences.getClass().getSimpleName());
SharedPreferences.Editor editor=sharedPreferences.edit();
editor.putString("s","bis").apply();
}
}
Here is the test:
#RunWith(MockitoJUnitRunner.class)
public class MockTest {
#InjectMocks
SharedPreferenceManager sharedPreferenceManager;
#Mock SharedPreferences sharedPreferences;
#Before
public void setup() {
MockitoAnnotations.initMocks(this);
}
#Test
public void isSharedPefWorking(){
sharedPreferenceManager.saveString("bis");
assertEquals("bis",sharedPreferenceManager.doSomething());
}
}
SharedPreferences uses a SharedPreferences.Editor which you're not currently mocking.
You would need to do something like the following to mock and verify the behaviour of your SharedPreferenceManager.
#RunWith(MockitoJUnitRunner.class)
public class MockTest {
#InjectMocks
SharedPreferenceManager sharedPreferenceManager;
#Mock
SharedPreferences sharedPreferences;
#Mock
SharedPreferences.Editor sharedPreferencesEditor;
final String savedString = "savedString";
#Before
public void setup() {
MockitoAnnotations.initMocks(this);
when(sharedPreferences.edit()).thenReturn(sharedPreferencesEditor);
when(sharedPreferencesEditor.putString(anyString(), anyString())).thenReturn(sharedPreferencesEditor);
}
#Test
public void saveString() {
sharedPreferenceManager.saveString(savedString);
verify(sharedPreferencesEditor).putString("s", savedString);
}
#Test
public void getString() {
when(sharedPreferences.getString("s","")).thenReturn(savedString);
String preferenceString = sharedPreferenceManager.doSomething();
assertEquals(preferenceString, savedString);
}
}

Uses of Mockit.reset() on a mock object

Is it right to use Mockito.reset() in #Before method for mock objects which is being used in more than test method in the same test Class as shown below.
public class SampleTest {
#Mock
private CustomRepository customRepo;
#Before
public void setUp() {
Mockito.reset(customRepo);
}
#Test
public void test1(){
......
given(customRepo.someMethod()).willReturn(Answer1);
......
}
#Test
public void test2(){
......
given(customRepo.someMethod()).willReturn(Answer2);
......
}
}
You don't have to reset the mock because JUnit/Mockito creates a new instance of SampleTest and the mock object for each test.

Mockito Mock log4j appender is not invoked while running unit test

I am trying to unit test the log statements generated in my code. I am using slfj, log4j and Mockito. I am using the similar code as below from the blog at
http://bloodredsun.com/2010/12/09/checking-logging-in-unit-tests/
When I run the test it throws exception saying that there are 0 invocations at line:
verify(mockAppender).doAppend(captorLoggingEvent.capture());
Error Message:
Wanted but not invoked: mockAppender.doAppend();
-> at testClass.testLogAdviceAfterReturning(DpsOpsLoggerTest2.java:94) Actually, there were zero interactions with this mock.
I see the logs printed on the console though. Request you to kindly help.
#RunWith(MockitoJUnitRunner.class)
public class ExampleThatLogsTest {
#Mock
private Appender mockAppender;
#Captor
private ArgumentCaptor captorLoggingEvent;
#Before
public void setup() {
LogManager.getRootLogger().addAppender(mockAppender);
}
#After
public void teardown() {
LogManager.getRootLogger().removeAppender(mockAppender);
}
#Test
public void shouldConcatAndLog() {
//given
ExampleThatLogs example = new ExampleThatLogs();
//when
String result = example.concat("foo", "bar");
//then
assertEquals("foobar", result);
verify(mockAppender).doAppend(captorLoggingEvent.capture());
LoggingEvent loggingEvent = captorLoggingEvent.getValue();
//Check log level
assertThat(loggingEvent.getLevel(), is(Level.INFO));
//Check the message being logged
assertThat(loggingEvent.getRenderedMessage(),
is("String a:foo, String b:bar"));
}
}
I tried to emulate your case ,At my end it is working fine
//Log Util
public class LogUtil{
final static Logger logger = Logger.getLogger(LogUtil.class);
public static Log`enter code here`ger getLogger()
{
return logger;
}
//class
public class RunMe {
public String runMe(String parameter) {
LogUtil.getLogger().info("This is info : " + parameter);
return "In runner " + parameter;
}
}
// Unit Test
#RunWith(MockitoJUnitRunner.class)
public class LoggerTest {
#Mock
private Appender mockAppender;
#Captor
private ArgumentCaptor captorLoggingEvent;
#Before
public void setup() {
LogUtil.getLogger().addAppender(mockAppender);
}
#Test
public void shouldConcatAndLog() {
RunMe runner=new RunMe();
String result=runner.runMe("XYZ");
assertEquals("In runner XYZ",result);
verify(mockAppender).doAppend((LoggingEvent) captorLoggingEvent.capture());
LoggingEvent logevent= (LoggingEvent) captorLoggingEvent.getValue();
assertThat(logevent.getLevel(), is(Level.INFO));
}
#After
public void tearDown() {
LogUtil.getLogger().removeAllAppenders();
}
}
I know this is a little bit outdated, but I was struggling with this too. I was logging statements at DEBUG level in the class under test. My configuration in logback.xml for the class under test was set to INFO. Changing my logging statement to INFO allowed the test to pass. In addition, I also read this Github post that is really concise and a clean implementation of testing log output. Hope others will find it useful.

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.