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

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.

Related

How to pass my DbContext object for testing using xunit and moq

Below mentioned is the test function that checks if details exist for the particular transactionId.
[Fact]
public async Task GetAllBlobDetails_Test()
{
_serviceScopeFactory.Setup(x => x.CreateScope().ServiceProvider.GetRequiredService<MriDbContext>()).Returns(_context);
BlobStatusEntity blobStatusEntity = await _bspRepository.GetBlobDetails("123");
Assert.NotNull(blobStatusEntity)
}
where _serviceScopeFactory is
Mock<IServiceScopeFactory> _serviceScopeFactory = new Mock<IServiceScopeFactory>();
(Microsoft.Extensions.DependencyInjection)
In the above function it calls _bspRepository.GetBlobDetails for particular transactionId ("123")
So here is the definition for GetBlobDetails
public async Task<BlobStatusEntity> GetBlobDetails(string transactionId)
{
if (String.IsNullOrEmpty(transactionId))
{
throw new ArgumentNullException(nameof(transactionId));
}
MriDbContext mriDbcontext = _scopeFactory.CreateScope().ServiceProvider.GetRequiredService<MriDbContext>();
return await mriDbContext.BlobStatus.FirstOrDefaultAsync(ele => ele.TransactionId == transactionId);
}
where _scopeFactory is IServiceScopeFactory _scopeFactory which is injected from the constructor.
When I am running the above test function GetAllBlobDetails_Test, I am getting the following error like this.
Message:
System.NotSupportedException : Unsupported expression: ... => ....GetRequiredService<MriDbContext>()
Extension methods (here: ServiceProviderServiceExtensions.GetRequiredService) may not be used in setup / verification expressions.
I am new to moq and xunit.
Please help me to resolve this issue.
Thanks in advance
So the root cause here is that you can't mock an extension method in Moq
You're doing this here:
_serviceScopeFactory.Setup(x => x.CreateScope().ServiceProvider.GetRequiredService<MriDbContext>()).Returns(_context);
GetRequiredService<T> is an extension method that extends IServiceProvider which you can see here
Depending on what the specific case you're trying to test is (are you testing the context creation, or the actual write to the DB?), you should be able to re-write your test to avoid mocking the extension method and mocking the public instance methods being used instead. You could even mock the actual instance method on IServiceProvider if you really wanted to keep the existing structure.
Further discussion of this topic exists here. That question uses MSTest rather than XUnit, but your issue here is specific to Moq.
Here is the initialization part
private BspRepository _bspRepository;
private Mock<IServiceScopeFactory> _serviceScopeFactory;
private Mock<ILogger<BspRepository>> _logger;
private Mock<IMapper> _mapper;
private DbContextOptions<MriDbContext> _options;
private MriDbContext _context;
private Mock<IServiceProvider> _serviceProvider;
private Mock<IServiceScope> _serviceScope;
public BSPRepositoryTests()
{
_serviceScopeFactory = new Mock<IServiceScopeFactory>();
_logger = new Mock<ILogger<BspRepository>>();
_mapper = new Mock<IMapper>();
_serviceProvider = new Mock<IServiceProvider>();
_serviceScope = new Mock<IServiceScope>();
_options = SetupDBContext();
_context = new MriDbContext(_options);
_bspRepository = new BspRepository(_serviceScopeFactory.Object, _logger.Object, _mapper.Object);
SetupData();
SetupServices();
}
I resolved my error by mocking objects in this way
private void SetupServices()
{
_serviceProvider.Setup(x => x.GetService(typeof(MriDbContext))).Returns(_context);
_serviceScope.Setup(x => x.ServiceProvider).Returns(_serviceProvider.Object);
_serviceScopeFactory.Setup(x => x.CreateScope())
.Returns(_serviceScope.Object);
}

Null pointer exception while doing unit testing using Mockito

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

Injecting DbContext in constructor of Web api 2 controller

I am creating a small proof of concept asp.net web api 2 service with entity framework code first. The controller's constructor looks like
public AccountController: ApiController
{
private readonly DbContext context;
public AccountController(DbContext _context){
context = _context;
}
public AccountController(){context = new ApplicationContext();}
}
I need to unit test my controllers. How can I mock the DbContext class. Is there a simple way of doing this? I want to avoid all that repository pattern with lot of interfaces. Because it will be a way overkill for this prototype.
Its usually something like this if you use Nunit and Moq.
[TestFixture]
public class AccountControllerTest
{
private Mock<DbContext> mockContext;
private AccountController sut;
[SetUp]
public void TestSetup()
{
mockContext = new Mock<DbContext>();
var account = new Account() { Id = 123, Name = "Test Account" };
mockContext.SetUp(x => x.GetAccountOnContext()).Returns(account);
sut = new Controller(mockContext.Object) { Request = new HttpRequestMessage() };
sut.Request.Properties.Add(HttpPropertyKeys.HttpConfigurationKey, new HttpConfiguration());
}
[Test]
public void ControllerMethod_GetLogin_Test()
{
// assuming GetLogin calls GetAccount on DbContext()
var response = sut.GetLogin(someAccount);
Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
mockContext.Verify();
}
}
You basically want to mock out your external dependencies and test just what the SUT (System Under Test) is supposed to do. I would also strongly encourage to look at Fakes instead of mocks. In general fakes result in less brittle tests.
So in this case, you could have a FakeDbContext() that you can pass to the tests. The FakeDbContext() will behave more like the actual DbContext() but will do all those operations in-memory, so that your tests don't have a dependency with a real database.
Depending on the database you use, you can also look at starting an embedded version of the real database as a part of your tests. Just have to make sure to do the necessary stopping and clean up of the test database records after the test run is complete in the TearDown() method.

EasyMock servlet reflection

That is a piece of servlet code. I have no idea how to cover it by mock. I created mock objecs like ServletConfig, LoginServiceFactory and LoginService but I don't know how to create mock for Class.forName. That is static method called and other methods like newInstance or getConstructor. I tried to call lsf.getClass().newInstance() expect in mock but it didn't work. Do you have any idea how to solve it? Thank's in advance.
public void init(ServletConfig config) throws ServletException {
super.init(config);
try {
String loginServiceFactoryName = config
.getInitParameter("LoginServiceFactory");
LoginServiceFactory lsf = (LoginServiceFactory)
Class.forName(loginServiceFactoryName).getConstructor().newInstance();
UserDataBase db = lsf.getUserDataBase();
Encoder encoder = lsf.getEncoder();
loginService = new LoginService(db, encoder);
}
Now I know answer for this problem, I should create implementation of LoginServiceFactory and search it by Reflection so in init parameter there will be name of my class whitch implements interface LoginServiceFactory.

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