I have a piece of code to test -
public class Test {
public List<Long> getListExpiryTime(long time){
List<Long> tempList = new ArrayList<Long>();
tempList.add(getExpiryTime(time));
return tempList;
}
private long getExpiryTime(long time) {
long currentTime = Calendar.getInstance().getTimeInMillis();
return time - currentTime / 1000;
}
}
I want to test whether the List returned has a certain value after I give an input time and we mock Calendar.getInstance().getTimeInMillis();. How exactly do I do this? I prefer to do this using Mockito
Calendar.getInstance is a static method and cannot be mocked with Mockito. PowerMockito could be of help but I strongly suggest to move away from Calendar and use the new time APIs from java.time. Your business component get a Clock injected that you can easily mock with Mockito.
Create a method e.g. getCurrentTime() which only returns Calendar.getInstance().getTimeInMillis(); in a new class like Helper.
Then you can mock this method like this:
Calendar date = new GregorianCalendar();
date.set(...)
Mockito.when(helperMock.getCurrentTime()).thenReturn(date);
Related
I want to test how often a method was called.
Im using EasyMock. This is what I have atm.
#TestSubject
Account account = new Account("acc");
#Mock
CheckoutMethod checkoutMethod;
#Mock
CheckoutMethod checkoutMethod2;
#Test
void test_account () {
List<CheckoutMethod> methods = new ArrayList<>();
Item item1 = new Item(1.);
expect(checkoutMethod.pay(item1)).andReturn(true);
expect(checkoutMethod2.pay(item1)).andReturn(true);
replay(checkoutMethod);
replay(checkoutMethod2);
methods.add(checkoutMethod);
methods.add(checkoutMethod2);
account.setCheckoutMethods(methods);
boolean should_work = account.checkoutFor(item1);
Assertions.assertTrue(should_work);
verify(checkoutMethod, expectLastCall().times(1));
verify(checkoutMehtod2, expectLastcall().times(0));
}
the last part is critical and what I want to check.
Im using verify(checkoutMethod, expectLastCall().times(1)); to check if the method is called once and verify(checkoutMehtod2, expectLastCall().times(0)); to verify that the method hasn't been called once.
Can this be done this way?
This is not mockito, it's EasyMock. EasyMock will require a recording and the verify() will verify all the expectations at once.
So, in your case, not called means not recorded. So you test becomes this:
Item item1 = new Item(1.0);
expect(checkoutMethod.pay(item1)).andReturn(true);
replay(checkoutMethod, checkoutMethod2);
List<CheckoutMethod> methods = Arrays.asList(checkoutMethod, checkoutMethod2);
account.setCheckoutMethods(methods);
boolean should_work = account.checkoutFor(item1);
assertTrue(should_work);
verify(checkoutMethod, checkoutMethod2);
I am fairly new to Mockito. I am not sure how to test the void function emitcount() or to actually test the class to 100%?
#AllArgsConstructor(onConstructor = #__(#Inject))
public class MetricsFactoryProvider {
private MetricsFactory metricsHelper;
public void emitCount(final String metricName, final double metricCount, final long startTime) {
if (StringUtils.isBlank(metricName)) {
return;
}
try {
Metrics metrics = metricsHelper.newMetrics();
metrics.addDate("StartTime", startTime);
metrics.addCount(metricName, metricCount, Unit.ONE);
metrics.close();
} catch (Throwable t) {
throw some exception();
}
}
This is the code I have so far
public class MetricsFactoryProviderTest {
#Mock
Metrics metrics;
#Mock
MetricsFactory metricsHelper;
public void testemitCountfromMetricsFactoryProvider() {
metricsHelper = new MetricsHelper();
Metrics metrics = metricsHelper.newMetrics();
metrics.addDate("StartTime", System.currentTimeMillis());
metrics.addCount("some", 1, Unit.ONE);
MetricsFactoryProvider metricsFactoryProvider = new MetricsFactoryProvider(metrics.getMetricsFactory());
metricsFactoryProvider.emitCount("some metric name",1,System.currentTimeMillis());
Assert.assertNotNull(metricsFactoryProvider);
}
How do I test emitfunction? My thought process
donothing(when(metricsFactoryProvider.emitfunction(pass args)))
Or Do I have to use ArgumentCaptor() ? How do I verify that the function emitfunction is called and metricsFactoryProvider object has correct data?
This here:
#Mock
Metrics metrics;
together with
Metrics metrics = new MetricsHelper().newMetrics();
simply doesn't make any sense. Your test class defines a mocked Metrics object - but then create another real metrics objects which you then pass to your class under test.
It is pretty simple: when you can verify the expected behavior using a real object - then do that. Otherwise, you use a mock.
And then you could do things like
MetricsFactoryProvider underTest = new MetricsFactoryProvider(mockedHelper);
underTest.emit(...);
verify(mockedHelper).add(eq("Start Date"), any());
just for example. In that sense: don't try to learn mocking by trial and error. It is too complicated for that. Instead: read and follow a good tutorial, like this one.
But just to give a short hint here: there are two different cases for using mocks.
Whatever mockedFoo = mock(Whatever.class);
when(mockedFoo.bar()).thenReturn("something else");
UnderTest underTest = new UnderTest(mockedFoo);
assertThat(underTest.foo(), is("something else"));
The above uses a "mocking specification" so that the class under test can do its job. You need to control the mock to do something inside your test. Compare that to:
Whatever mockedFoo = mock(Whatever.class);
UnderTest underTest = new UnderTest(mockedFoo);
assertThat(underTest.foo(), is("something else"));
verify(mockedFoo).bar("expected"parm");
In this case, you want check that a certain expected call happened.
I'm trying to test a class, every method is tested except for the last one, this one is kinda tricky for me because it calls another method in the same class and uses it's return value to return a string to the user.
/**
* Get the total time elapsed as a
* human readable string
*
* #return string
*/
public function getElapsedTimeString()
{
$elapsed = $this->getElapsedTime();
return "{$elapsed} seconds elapsed.";
}
In order to test it i need to make sure that $this->getElapsedTime() will return a set value like 5 or 6, i've been trying to do this with mocks, but it's not working, it returns null every single time.
public function testGetElapsedTimeStringMethod()
{
// Create Mock of the CarbonTimer class
$mock = $this->getMockBuilder(CarbonTimer::class)
->getMock();
// Configure the Mock Method
$mock->method('getElapsedTime')
->willReturn(5);
$this->assertEquals("5 seconds elapsed.", $mock->getElapsedTimeString());
}
What am i missing here? Sorry in advance if it's a dumb question, i'm just getting started with PHPUnit and it's a bit overwhelming
Got it to work like this, simply used setMethods with the name of the method i wanted to override, no idea why this worked yet, but it did.
public function testGetElapsedTimeStringMethod()
{
// Create Mock of the CarbonTimer class
$stub = $this->getMockBuilder(CarbonTimer::class)
->setMethods(['getElapsedTime'])
->getMock();
// Configure the Mock Method
$stub->method('getElapsedTime')
->willReturn(5);
$this->assertEquals("5 seconds elapsed.", $stub->getElapsedTimeString());
}
I am still trying to get the hang of unit testing, I have a simple question. Today I wanted to write a test for a very simple function. This function was doing just this:
void OnSomething()
{
increment++;
if (increment == 20)
SaveIt();
}
I said, this function could be testable. I could write a test that calls it 20 times and then verifies that SaveIt has been called.
Then my doubt arose. How can I test that SaveIt has been called? My first answer was to add a boolean, but then I thought: is it correct to add class features just to make it testable?
Please advise. Thank you.
I would suggest having SaveIt return a success or failure result, this just makes it easier to test overall. You could do something as simple as having it return a bool, or you could create a generic result class that contains the ability to set messages as well, if you ever need to report whether it passed or failed.
A simple example example
public class Result
{
public bool IsSuccess;
public List<string> Messages;
}
In the unit test you're trying to test only the OnSomething behavior though -- what happens inside "SaveIt" should not be tested. So ideally you'd want SaveIt() to occur in another class so you can mock its response.
I use Moq for this purpose. Moq is free, you can get it here: http://code.google.com/p/moq/
my method would then become
Result OnSomething()
{
Result result=null;
increment++;
if(increment == 20)
{
result = saver.SaveIt();
}
return result;
}
Your class constructor would take an object that implements ISaver interface (defining SaveIt() method) (ideally injected by a DI framework but you could generate it manually if you had to).
Now in your unit test you would create a mock version of ISaver and tell it what to return when it gets called:
Mock<ISaver> mock = new Mock<ISaver>();
mock.Setup(x=> x.SaveIt()).Returns(new Result{IsSuccess=true});
You'd instantiate your class passing mock.Object in the constructor ISaver parameter.
ex.
MyClass myClass = new MyClass(mock.Object);
//(assuming it didn't have other parameters)
Then, you could Assert whether result is null or not -- if it never got called, it would be null because the setup you did above would never trigger.
(in nunit)
Result result = myClass.OnSomething();
Assert.IsNotNull(result);
If you really didn't want OnSomething() to return a result, or it couldn't because it's an event, then I would have OnSomething() call a method to do the work for you:
void OnSomething()
{
Result result = DoTheWork();
}
Result DoTheWork()
{
Result result=null;
increment++;
if(increment == 20)
{
result = saver.SaveIt();
}
return result;
}
And then run your unit test on DoTheWork() instead of OnSomething().
Definitely not! Production code should not depend on tests at all, but the tests should verify the correct behaviour of the actual code. This can be achieved by several methods, such as IOC, and using mocks. You can take a look at some existing frameworks which simplify your life a lot:
http://code.google.com/p/mockito/
http://code.google.com/p/jmockit/
http://www.easymock.org/
a very simple method, but don't know what's to test!
I'd like to test this method in Business Logic Layer, and the _dataAccess apparently is from data layer.
public DataSet GetLinksByAnalysisId(int analysisId)
{
DataSet result = new DataSet();
result = _dataAccess.SelectAnalysisLinksOverviewByAnalysisId(analysisId);
return result;
}
All Im testing really is to test _dataAccess.SelectAnalysisLinksOverviewByAnalysisId() is get called!
here's my test code (using Rhino mock)
[TestMethod]
public void Test()
{
var _dataAccess = MockRepository.GenerateMock<IDataAccess>();
_dataAccess.Expect(x => x.SelectAnalysisLinksOverviewByAnalysisId(0));
var analysisBusinessLogic = new AnalysisLinksBusinessLogic(_dataAccess);
analysisBusinessLogic.GetLinksByAnalysisId(0);
_dataAccess.VerifyAllExpectations();
}
Let me know if you writing the test for this method what would you test against?
Many Thanks!
Your proposed example test doesn't test the method in question, but rather an overload with the same name.
Another issue is that the expectation set up for the mock doesn't match the method called. Again, it's another overload.
The third thing that comes into my mind is that you don't need to perform an interaction-based test here. Since the method under test has a return value, you can perform a simple state-based test.
Here's one possible alternative:
[TestMethod]
public void Test()
{
var id = 1;
var expectedResult = new DataSet();
var dataAccess = MockRepository.GenerateStub<IDataAccess>();
dataAccess.Stub(x => x.SelectAnalysisLinksOverviewByAnalysisId(1))
.Return(expectedResult);
var analysisBusinessLogic = new AnalysisLinksBusinessLogic(dataAccess);
var result = analysisBusinessLogic.GetLinksByAnalysisId(id);
Assert.AreEqual(expectedResult, result);
}
actually what you think this little tweak?
dataAccess.Expect(x =>
x.SelectAnalysisLinksOverviewByAnalysisId(1)).Return(expectedResult);
Assert.AreEqual(expectedResult, result);
dataAccess.VerifyAllExpectations();
that way we doing the Assert as well as expect the SelectAnalysisLinksOverviewByAnalysisId() being called
What's your thoughts?