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);
Related
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.
In a spring-boot application, I do some call to moneris. I would like to mock this part.
In a service class:
#Transactional
#Override
public void saveCreditCard(CreditCardInfoDto creditCardInfo) throws CreditCardException, ResourceNotFoundException {
...
ResolveData resdata = null;
ResolverReceipt resreceipt = null;
...
ResAddCC resAddCC = new ResAddCC(creditCardInfo.getCreditCard(), expirationDate, String.valueOf(paymentGateway.getCryptType()));
resAddCC.setCustId(member.getMemberId().toString());
ResolverHttpsPostRequest mpgReq = new ResolverHttpsPostRequest(paymentGateway.getHost(), paymentGateway.getStoreId(), paymentGateway.getApiToken(), resAddCC);
resreceipt = mpgReq.getResolverReceipt();
resdata = resreceipt.getResolveData();
...
if (resreceipt != null && resreceipt.getResponseCode() != null && Integer.getInteger(resreceipt.getResponseCode()) < 50) {
...
}
When I debug, i see then resreceipt is not null, same thing with resreceipt.getResponseCode() but that do un Null Pointer Exception on this line.
Real value vs Mock?
It seem that unreal call is done to moneris... I would like to avoid that.
In my class test I have:
#InjectMocks
PaymentServiceImpl paymentService;
#Mock
MemberRepository memberRepository;
#Mock
PaymentGatewayConfigRepository paymentGatewayConfigRepository;
#Mock
OperationRepository operationRepository;
#Mock
ResolverReceipt resreceipt;
#Mock
ResolverHttpsPostRequest mpgReq;
#Before
public void initMocks() {
MockitoAnnotations.initMocks(this);
}
Mockito.when(memberRepository.findOne(memberId)).thenReturn(member);
Mockito.when(paymentGatewayConfigRepository.findAll()).thenReturn(paymentsGateway);
ResolverReceipt resreceipt = new ResolverReceipt("<?xml version=\"1.0\" encoding=\"UTF-8\"?> <receipt> <DataKey>iZxTfRWZaRd3S2lajvoZaPA22</DataKey> <ReceiptId>null</ReceiptId> <ReferenceNum>null</ReferenceNum> <ResponseCode>001</ResponseCode> <ISO>null</ISO> <AuthCode>null</AuthCode> <Message>Successfully registered CC details.</Message> <TransTime>19:13:52</TransTime> <TransDate>2016-12-09</TransDate> <TransType>null</TransType> <Complete>true</Complete> <TransAmount>null</TransAmount> <CardType>null</CardType> <TransID>null</TransID> <TimedOut>false</TimedOut> <CorporateCard>null</CorporateCard> <RecurSuccess>null</RecurSuccess> <AvsResultCode>null</AvsResultCode> <CvdResultCode>null</CvdResultCode> <ResSuccess>true</ResSuccess> <PaymentType>cc</PaymentType> <IsVisaDebit>null</IsVisaDebit> <ResolveData> <cust_id>1</cust_id> <phone>4506777244</phone> <email>paul.smith#gmail.com</email> <note></note> <crypt_type>0</crypt_type> <masked_pan>4242***4242</masked_pan> <expdate>1601</expdate> </ResolveData> </receipt> ");
Mockito.when(mpgReq.getResolverReceipt()).thenReturn(resreceipt);
Basically, you need to create a seam in your code where you can alter the code's behavior without changing the code, itself. Essentially, you inject dependencies, rather than having the code instantiate dependencies so that you can mock dependencies when testing. Presently, in your test code, you're forced to use the real value of resAddCC and mpgReq because the current production code instantiates them via the new keyword, rather than using an injected factory and then calling the factory method on the factory object. Using such a factory, you could mock the factory and its call, where it would otherwise call out to Moneris.
I am new to FakeItEasy and try solve a problem.
I have a class
public class Events
{
public List<Events> SaveEvents()
{
// Call to repository and return 1(success) or -1(fail)
//If the repository return 1 then need to make another call to save the action in db
//Sample Code here
AuditLogService log = new AuditLogService();
log.CallLog();
}
}
Here is the Test Code:
[TestMethod]
public void EventValidation()
{
//Arrange
var Fakeevents = A.Fake<Events>();
var log = A.Fake<AuditLogService>();
var _EventsController = new EventsController(Fakeevents);
_EventsController.SaveEvents();
A.CallTo(
() => Fakeevents.SaveEvents().Retunr(1).AssignsOutAndRefParameters(status)
A.CallTo(
() => log.CallLog()).MustHaveHappened(Repeated.AtLeast.Once);
}
I am getting error like "Non virtual methods can not be intercepted"
I want to check whether the Calllog method is called after success or not.
Can anyone please help me on this.
I have a method and inside a method i am initiating another class and calling a method of the class. I want to check from fakeItEasy whether the method is called.
Unfortunately, your title says it all. Non-virtual members cannot be faked, configured, or intercepted, as noted in the documentation under "What members can be overridden?".
There's nothing that FakeItEasy can do for you unless you make the member virtual (or promote it to an interface and fake the interface, or something similar).
Have you tried to use function?
Like this:
Func<YourReturnType> action = () => YourMethod(params); // Act
action.Should().Throw<Exception>(); // Assert
var log = A.Fake();
Use interface instead of AuditLogService. And have this class implement that interface
var log = A.Fake();
I am using Moq in my unit test project. Most unit test examples I've seen online end with someMock.VerifyAll(); I wonder if it is OK to assert after VerifyAll(). So for example,
//Arrange
var student = new Student{Id = 0, Name="John Doe", IsRegistered = false};
var studentRepository = new Mock<IStudentRepository>();
var studentService= new StudentService(studentRepository.Object);
//Act
studentService.Register(student); //<-- student.IsRegistered = true now.
//Verify and assert
studentRepository.VerifyAll();
Assert.IsTrue(student.IsRegistered);
Any thought? Thank you.
No you should not use both together in most cases(there are always exceptions). The reason for that is you should be testing only one thing in your test for maintainability, readability and few other reasons. So it should be either Verify(VerifyAll) or Assert in your test and you name your tests accordingly.
Look at Roy Osherove's article about it:
http://osherove.com/blog/2005/4/3/a-unit-test-should-test-only-one-thing.html
VerifyAll is used to make sure certain methods are called and how many times. You use mocks for that.
Assert is used for verifying the result returned from the method you are testing. You use Stubs for that.
Martin fowler has a great article explaining the difference between mocks and stubs. If you understand it you will know the difference better.
http://martinfowler.com/articles/mocksArentStubs.html
UPDATE: example of mock vs stub using Moq as requested in the comment below. I have used Verify but you can use VerifyAll as well.
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
...
[TestClass]
public class UnitTest1
{
/// <summary>
/// Test using Mock to Verify that GetNameWithPrefix method calls
/// Repository GetName method once when Id is greater than Zero
/// </summary>
[TestMethod]
public void GetNameWithPrefix_IdIsTwelve_GetNameCalledOnce()
{
// Arrange
var mockEntityRepository = new Mock<IEntityRepository>();
mockEntityRepository.Setup(m => m.GetName(It.IsAny<int>()));
var entity = new EntityClass(mockEntityRepository.Object);
// Act
var name = entity.GetNameWithPrefix(12);
// Assert
mockEntityRepository.Verify(
m => m.GetName(It.IsAny<int>()), Times.Once);
}
/// <summary>
/// Test using Mock to Verify that GetNameWithPrefix method
/// doesn't calls Repository GetName method when Id is Zero
/// </summary>
[TestMethod]
public void GetNameWithPrefix_IdIsZero_GetNameNeverCalled()
{
// Arrange
var mockEntityRepository = new Mock<IEntityRepository>();
mockEntityRepository.Setup(m => m.GetName(It.IsAny<int>()));
var entity = new EntityClass(mockEntityRepository.Object);
// Act
var name = entity.GetNameWithPrefix(0);
// Assert
mockEntityRepository.Verify(
m => m.GetName(It.IsAny<int>()), Times.Never);
}
/// <summary>
/// Test using Stub to Verify that GetNameWithPrefix method
/// returns Name with a Prefix
/// </summary>
[TestMethod]
public void GetNameWithPrefix_IdIsTwelve_ReturnsNameWithPrefix()
{
// Arrange
var stubEntityRepository = new Mock<IEntityRepository>();
stubEntityRepository.Setup(m => m.GetName(It.IsAny<int>()))
.Returns("Stub");
const string EXPECTED_NAME_WITH_PREFIX = "Mr. Stub";
var entity = new EntityClass(stubEntityRepository.Object);
// Act
var name = entity.GetNameWithPrefix(12);
// Assert
Assert.AreEqual(EXPECTED_NAME_WITH_PREFIX, name);
}
}
public class EntityClass
{
private IEntityRepository _entityRepository;
public EntityClass(IEntityRepository entityRepository)
{
this._entityRepository = entityRepository;
}
public string Name { get; set; }
public string GetNameWithPrefix(int id)
{
string name = string.Empty;
if (id > 0)
{
name = this._entityRepository.GetName(id);
}
return "Mr. " + name;
}
}
public interface IEntityRepository
{
string GetName(int id);
}
public class EntityRepository:IEntityRepository
{
public string GetName(int id)
{
// Code to connect to DB and get name based on Id
return "NameFromDb";
}
}
Yes you should call the assert.
VerifyAll() will assert that all SetUp() calls were actually called.
VerifyAll() will not confirm that your student object is registered. Because there are no SetUp() calls in your test case, I think VerifyAll() isn't verifying anything.
I would absolutely expect to see Verify and Assert used side-by-side within a unit test. Asserts are used to validate that properties of your system under test have been set correctly, whereas Verify is used to ensure that any dependencies that your system under test takes in have been called correctly. When using Moq I tend to err on the side of explicitly verifying a setup rather than using the VerifyAll catch-all. That way you can make the intent of the test much clearer.
I'm assuming in the code above that your call to the student repository returns a boolean to state that the student is registered? And you then set that value on the student object? In that case, there is a valuable setup that needs to be added, in which you are effectively saying that when the student repository method is called, it will return true. Then you Assert that student.IsRegistered is true to ensure that you have set the property correctly from the repository return value and you Verify that the repository method is called with the inputs that you are expecting.
There's nothing intrinsically wrong with both asserting and verifying in a mocking test, though assertions that depend on the actual methods being called are likely to fail, because the mock methods do not have the same effects as the real methods.
In your example it is probably fine, as only the repository is mocked, and the change of the student state is presumably done in the service.
Whether both verify and assert should be done in the same test is to a degree a matter of taste. Really the verify is checking that the proper calls to the repository are made, and the assert is checking that the proper change to the entity is made. As these are separate concerns, I'd put them in separate tests, but that may just be me.
I am trying to test the following code
public void CleanUp()
{
List<ITask> tasks = _cleanupTaskFactory.GetTasks();
//Make sure each task has the task.Execute() method called on them
}
In my test I create a mocked implementation of _cleanupTaskFactory, and I want to stub the GetTasks() method to return a type:
List<Mock<ITask>>
...but the compiler won't accept that as a return value.
My goal is to ensure that each task returned has the .Execute() method called on it using the Verify() MoQ method.
How can I assert that each task gets executed?
In your _cleanUpTaskFactory mock you could simply do something like the following:
var mocks = new List<Mock<ITask>>();
for(var i = 0; i < 10; i++){
var mock = new Mock<ITask>();
mock.Setup(t => t.Execute()).Verifiable();
mocks.Add(mock);
}
_cleanUpTaskFactoryMock.Setup(f => f.GetTasks()).Returns(mocks.Select(m => m.Object).Tolist());
Now make sure to keep a reference to the mocks list, and when you done with your testing you iterate over all the mocks and call Verify() like so:
mocks.ForEach(m => m.Verify());