Null pointer exception while doing unit testing using Mockito - spring-mvc

I am new with Mockito. I am writing unit test cases for SomeDaoImplclass
this is the method in SomeDaoImplClass
#Override
Public SomeModelClass retriveSomeDetails(int a,long b){
return retrieveSomeDetails(a,b,Enum.Active)
}
Here is my test class
#Mock
private SomeDaoImplClass someDaoImplClass
#Mock
private NamedParameterJdbcTemplate jdbcTemplate
#Mock
DataSource dataSource
#Mock
SomeDaoClass someDaoClass
#Before
Public void setUp() throws Exception {
someDaoImplClass = new SomeDaoImplClass();
dataSource = Mockito.mock(DataSource.class);
jdbcTemplate = Mockito.mock(NamedParameterJdbcTemplate.class);
someDaoClass = Mockito.mock(SomeDaoClass.class);
SomeDaoImplClass.setDataSource(dataSource);
SomeDaoImplClass.setSomeDaoClass(someDaoClass);
}
#Test
public void testSomeData(){
Modelclass modelclass = new ModelClass();
Mockito.when(SomeDaoClass.retriveSomeDetails(Mockito.anyInt(),Mockito.anyLong())).thenReturn(modelClass);
ModelClass object2 = SomeDaoImplClass.retriveSomeDetails(01,1000L,Class.Active);
Assert.assertEquals(01,1000L, object2);
}

First of all, i highly recommend to you, to take a look at [1] (but be careful to use the right version
Second you do make some initial mistakes.
you want to test SomeDaoImplClass but you are creating a mock, so you are not really testing the class
i do not see if you are using the MockitoJUnitRunner, but based on your code and implementation, i assume not. So you need to MockitoAnnotations.initMocks(this) or use a JUnitRule
you are using static getters and setters to set your "DaoImplClass" and other needed classes, i do not know your implementation, but i am quite sure, it should be
someDaoImplClass.setDataSource(daraSource);
instead of
SomeDaoImplClass.setDataSource(daraSource);
your test does not seem to make sense at the moment at all, what do you want to test? and what is your goal. You should definitely provide more context when asking questions, and review your whole "question" before posting
[1] http://static.javadoc.io/org.mockito/mockito-core/2.8.9/org/mockito/Mockito.html

Related

Avoid HasData Seed DbContext in EF Core 2.2 during Unit Tests

In my ASP.Net CORE 2.2/EF Core 2.2 web API app, I have a HasData() method in my DbContext to seed the DB with some standard data that I use. However, I don't want to use that data when running my xUnit tests.
My unit tests use the Sqlite in-memory provider and as part of that process, it requires a call to EnsureCreated(). Well, EnsureCreated() calls OnModelCreating() which calls HasData(), so my unit test context now contains all of my HasData seed data, which I don't want. I want to seed my unit tests with different, very specific data.
Because EnsureCreated() seeds the context, and then I try adding my unit test specific seed data, I end up with both sets of data in my test DbContext and my tests fail.
How can I bypass the HasData call for my unit tests?
Instead of trying to bypass HasData(), you could instead conditionally not supply data to that method.
Quick example - if you move the pre-pop data out to e.g. "DataInitialiser" classes:
builder.HasData(new UserDataInitialiser().Data);
Then set a static flag in a base class:
public abstract class DataInitialiserControl
{
public static bool SkipInitData { get; set; } // ** flag **
}
public abstract class DataInitialiser<T> : DataInitialiserControl
{
public IList<T> Data => SkipInitData ? new List<T>() : GetData();
protected abstract IList<T> GetData();
}
Your DataInitialisers would look like this:
public class UserDataInitialiser : DataInitialiser<User>
{
protected override IList<User> GetData()
{
return new[]
{
new User {Id = 1, Name = "Bob"}
};
}
}
You could then just set the static flag in your test initialisation:
public abstract class TestBase
{
protected DbContextOptions<MyContext> DbOptions { get; private set; }
[TestInitialize]
public void InitializeDatabase()
{
// ** SKIP DATA PRE-POP **
DataInitialiserControl.SkipInitData = true;
DbOptions = BuildDbContextOptions(new DbContextOptionsBuilder<MyContext>()).Options;
using (var context = GetContext())
{
context.Database.EnsureCreated();
}
}
[TestCleanup]
public void ClearDatabase()
{
using (var context = GetContext())
{
context.Database.EnsureDeleted();
}
}
}
(Code untested, but should be more or less right).
You could always mock the call with Mock it will provides a way to mock an interface making it so the function calls of the said mocked interface will actually be calling your mocked function. This will provide a way for you to override the function call to HasData.
Of course, this means if it isn't already using an interface for that function(s) you'll have to wrap it in one.
Here are a few useful examples to Mocking: writing unit tests with NUnit and Moq and an introduction to unit testing with mocks(using moq).
I also suspect that Theory attribute and inline data could be of use to you.
Creating parameterized tests in xUnit
Hope that helps.

Wanted but not invoked: There were zero interactions with this mock

I am stuck with this issue for the whole day. Tried many resources and debug features but no luck.
Can you guys please help me.
public class Data{
DataDriver dataDriver; // DataDriver is a different class which I have injected.
Connector connector; // Connector is a different class which I am injecting in Data class.
// Constructor and Setter methods
public void read(){
CloseableHttpClient client = HttpClients.createDefault();
Hashmap<String, String> credentials = dataDriver.run(new Date());
HttpGet get = connector.execute(client,credentials);
}
}
For my test class, I am using Powermockito, as HttClients.createDefault() is a static method.
#ContextConfiguration(locations = { "classpath:/XXX.xml" })
#RunWith(PowerMockRunner.class)
public class DataTest {
Data mockeddata;
#Mock
Connector mockedconnector;
#Mock
DataDriver mockeddataDriver;
#Mock
CloseableHttpClient mockedClient;
#Before
public void Setup() {
MockitoAnnotations.initMocks(Data.class);
mockeddata =new Data();
PowerMockito.mockStatic(HttpClients.class);
mockedData.setConnector(mockedconnector);
mockedData.setDataDriver(mockedDataDriver);
}
#Test
#PrepareForTest({ HttpClients.class })
public void testRead(){
HashMap<String, String> credentials = new HashMap<String, String>();
PowerMockito.when(HttpClients.createDefault()).thenReturn(mockedClient);
PowerMockito.when(mockeddataDriver.run(newDate())).thenReturn(credentials);
PowerMockito.when(mockedconnector.execute(mockedClient,credentials)).thenReturn(new HttpGet());
verify(mockedconnector, atLeastOnce()).execute(mockedClient, credentials);
}
}
It says zero interactions with the connector mock. Its not complaining on the dataDriver mock. I tried debugging and was able to see both my mock objects in the Data class. But its not going into the execute funtion of the Connector.
Any advise on what I am doing wrong?
Thank You
Maybe when you verify the parameters Mockito is creating different object references (different objects)...
Try verifying with eq() method to make sure that the parameters you expect are the same as when that you have defined before.
verify(mockedconnector,atLeastOnce()).execute(eq(mockedClient),eq(credentials));
You are not calling your read method from your test class.

How to Write a Mockito+Junit test case for a method which reads the properties from properties file

I have to write a Mockito+Junit test for a method and that method reads the data from a properties file. When I am trying to execute my test case the properties file is loading but it is returning null. Following is my code:
#RestController
#PropertySource("classpath:/com/example/prop.properties")
public class ReadProp {
#Value("${name}")
private String name;
#Value("${rollNo}")
private String rollNo;
#RequestMapping(value="/")
public void getDetails(){
System.out.println(name);
System.out.println(rollNo);
}
}
The test case is as follows
#RunWith(MockitoJUnitRunner.class)
#PropertySource("classpath:/com/example/prop.properties")
public class ReadPropTest {
#Mock
private ReadProp readProp;
#Value("${name}")
private String name;
#Value("${rollNo}")
private String rollNo;
#Test
public void readValues() {
System.out.println(name);
System.out.println(rollNo);
readProp.getDetails();
}
}
Let's start at the beginning... Your test has many problems, the first being that you don't actually have anything to test...
#Mock
private ReadProp readProp;
This, together with #RunWith(MockitoJUnitRunner.class) makes your readProp object a mock object. A mock object contains no logic. It has nothing to do with your original ReadProp class except the method names, etc. But the method themselves don't actually DO anything (unless you tell them to).
So, first problem: You are not test YOUR RealProp class, but a mock object, which doesn't help. You are creating something that only looks like a RealProp object and then you test that, but of course, that doesn't tell you anything. Mocks are there to help you simplify dependencies, etc. in your test - but it makes no sense to actually test the mock.
So, don't. Instead, make a real RealProp.
Another problem is, that System.out is not very good to test, but I assume that's just temporary code, so let's ignore that for a moment...
The next question is, what do you want to test. There are two possibilities:
a) You want to test that, under the assumption that the fields name and rollNo were filled correctly by whatever dependency injection framework (spring, in this case) you are using, the method getDetails will use them correctly.
b) You want to test that the injection of the values works and also the method getDetails uses that values.
These are two different tests. a) would be a true unit test, since it's limited to this "unit". b) would be more complex, since it doesn't just look at this unit, but also at the Spring environment around it. I would not go so far to call it an integration test, but it's more than a simple unit test.
Personally, I try to avoid the Spring environment in my unit tests as far as possible and concentrate on my own code, testing the Spring integration later in real integration tests, but that's as much personal preference as anything else.
Let's start with a)...
public class ReadPropTest {
private ReadProp readProp = new ReadProp();
#Before
public void init() {
Whitebox.setInternalState(readProp, "name", "someName");
Whitebox.setInternalState(readProp, "rollNo", "someRollNo");
}
#Test
public void myTest() {
...
}
}
Of course, you can also use Spring's ReflectionTestUtils instead of Mockito's Whitebox, doesn't matter.
And for b), you could try something like this. Of course you migth have to play around with the Configuration a bit, as it depends on your setup.
#RunWith(SpringJUnit4ClassRunner.class)
#WebAppConfiguration
#ContextConfiguration(locations = {"classpath:applicationContext-spring.xml" })
public class ReadPropTest {
#Autowired
private ReadProp readProp;
...
}

CDI Injection Within A Constructor

I've got my application setup to use CDI and all is going well. Now I'm creating a new bean that extends a class from a 3rd party library. I attempted to create something like the below example:
#Named("myNewClass")
#ConversationScoped
public class MyNewClass extends ThirdPartyClass {
#Inject
private ApplicationConfig applicationConfig;
#Override
public void doStuff() {
// In this code, applicationConfig will be null.
}
}
When doStuff is called, applicationConfig was always null. I added a no args constructor & a method tagged with #PostConstruct to try and see what was going on. The constructor gets called then the doStuff method. As doStuff is being called at construction time I cannot use the #Inject annotations at this point.
So my question is how do I get a hold of applicationConfig at this point?
I've been tinkering with BeanManager (this is in a function I call with ApplicationConfig.class as a parameter):
Context initCtx = new InitialContext();
Context envCtx = (Context) initCtx.lookup("java:comp/env");
BeanManager beanManager = (BeanManager) envCtx.lookup("BeanManager");
Bean myBean = beanManager.getBeans(clazz).iterator().next();
return beanManager.getReference(myBean, clazz, beanManager.createCreationalContext(myBean));
Which works but it's creating a new ApplicationConfig instance. I want to get the one that I know already exists on my ConversationScope.
A little info: I'm using Seam 3.0, Weld Servlet 1.1.1 and this is running on Tomcat 6.
You can annotate a constructor with #Inject then any parameters of the constructor become injection points which the BeanManager will resolve. It's certainly not the desired way of doing it, but if it works for you, go for it.

Verifying indirectly called methods with Moq on a mocked object

My app has a ProviderFactory static class that has static utility methods passing back static instances of things like a logger. The rest of my app then can just grab a/the reference to the logger from anywhere without having to pass in the logger (common design practice).
So, another part of my app, the DbCacheProvider, has methods that make calls to the logger so internally it gets a reference to the logger from the factory and then issues calls to it.
My question is that using Moq, I want to verify methods on the logger are being called by the methods within the DbCacheProvider. I can do this using dependency injection when I pass a mock logger into the DbCacheProvider as a parameter, but I'm not passing the logger in (not do I want to). So, how would I verify the DbCacheProvider is making calls to the logger?
If you don't want to pass the logger in through the constructor you'd need to change your ProviderFactory while running unit tests to return your mocked logger.
Anyway there are a couple of reasons it's often suggested to set up dependency injection:
Your tests are more straightforward and don't involve finagling with custom factories
IoC frameworks like Unity, Ninject and Autofac make it easy to create objects when their dependencies are set up this way. If you set up all of your objects this way, the framework will do all the heavy lifting of creating the right objects and passing them in for you. The dependency injection is done automatically and won't be a burden for you.
Old question without an answer, I had a similar problem and solved it like this:
I have the following sample code and need to verify that not only was a method called but was called with a specific value.
public interface ILog
{
void Info(string message);
}
public interface ILogFactory
{
ILog GetLogger();
}
This is the class being tested, where the interface items are being injected:
public class NewAction
{
readonly ILogFactory _logger;
public NewAction(ILogFactory logger)
{
_logger = logger;
}
public void Step1()
{
_logger.GetLogger().Info("Step 1");
}
public void Step2()
{
_logger.GetLogger().Info("Step 2");
}
}
This is obviously a very simplistic view of my actual code, but I needed to verify that Step1 and Step2 are behaving as expected and passed the correct values to the Log, this would mean I also needed to ensure they occurred in the right order. My test:
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
// Arrange
var log = new Mock<ILog>();
var factory = new Mock<ILogFactory>();
factory.Setup(l => l.GetLogger()).Returns(log.Object);
// Act
var action = new NewAction(factory.Object);
action.Step1();
action.Step2();
// Assert
factory.Verify(l => l.GetLogger());
log.Verify(l => l.Info(It.Is<string>(s => s == "Step 1")));
log.Verify(l => l.Info(It.Is<string>(s => s == "Step 2")));
}
}
Hope this helps.

Resources