Using phpunit mock object, I have a method that returns an object.
How do you code this using the expects / method / will methods?
i.e.
->will($this->returnValue('Class_Name'));
Create the object, and return it with the returnValue() function. For example:
$myObject = new RandomObject();
$myFactory = $this->getMock('ObjectFactory', array('getRandomObject'));
$myFactory->expects($this->any())->method('getRandomObject')->will($this->returnValue($myObject);
$this->assertInstanceOf('RandomObject', $myFactory->getRandomObject());
This will pass.
You can also create that object as a mock itself and pass the mock.
Related
I have the below class written
#implementation B
- (NSString *)returnMock{
return #"BBB";
}
#end
And I have the below test written:
- (void)testB {
id mockB = [OCMockObject mockForClass:[B class]];
[[[mockB stub] andReturn:#"mock"] returnMock];
//This check is a pass
XCTAssertEqualObjects(#"mock", [mockB returnMock]);
B *b = [[B alloc] init];
//This check is a fail
XCTAssertEqualObjects(#"mock", [b returnMock]);
}
As I understand that, if a mock is created for a class and then for any new instance of it will refer to the mocked class.
If this is not true, can anyone help me in making the second assert to pass after a new instance is created.
Thanks
A mock object can be used instead of an instance of the class. Creating a mock object does not affect instances of the class. If you want to mock methods in an existing instance you must use a partial mock for that specific instance.
I have a unit test that I am writing and have run into an annoying problem... Let's say I have the following function I am testing:
public function functionToTest(array &$data, parameter2)
{
// perform some action on the array that is being passed in by reference
}
Now, when I attempt to call this function in my unit test, I would do something like this:
public function testMyFunction()
{
$data = array('key1' => 'val1');
$mockOfClass = $this->getMockBuilder('ClassName')
->disableOriginalConstructor()
->setMethods(array('method1', 'method2')) // My function to test is NOT in this list
->getMock();
$this->mockOfClass->functionToTest($data, true);
// Perform assertions here
}
However, I receive the following error message:
Parameter 1 to ClassName::addNewFriendsToProfile() expected to be a reference, value given
This seemed very strange to me. First of all, I'm just passing an array by reference, so it it shouldn't have a problem with this. Secondly, Why parameter 1? Doesn't it mean parameter 0? Then, I tried changing the call to the following:
$this->mockOfClass->functionToTest(&$data, true);
After making this change, it works fine. Unfortunately, it also produces the following warning:
Call-time pass-by-reference has been deprecated in /PathToFile on line xxx
I do not encounter this error when running the actual code. It only throws this error in the unit test. Also, I need to use the mock as there are methods in the class I am mocking; So I can't simply create a new instance of the class and call the method that is being tested. Is there any way I can get around this?
It turns out that PHPUnit clones each of the parameters that are being passed in (Thanks Tim Lytle for pointing me to this source: Pass by reference in a callback when mocking in PHPUnit). This is what causes the error if the array is passed in without a reference at call-time in the unit test. Luckily, the solution is simple. Instead of passing the array by reference, I pass in the array by value and return the array.
before:
public function someFunction(array &$myArray)
{
$myArray[] = 'new val';
}
after:
public function someFunction(array $myArray)
{
$myArray[] = 'new val';
return $myArray;
}
Im new to mvc 3 and I'm doing unit tests. I'm testing a search action method. This method returns an action method that contains a generic list of some type. How do I test if the model data returned is of that specified type?
Please help.
In your test method you do a type assertion after you have obtained the search results in a variable. Here is an assert for NUnit:
var searchResults = SearcherUnderTest.Search("TestKeyword");
Assert.IsInstanceOfType( Type expected, object searchResults );
Do you mean that you want to test the type of T in a List? If so then look at this question: How to get the type of T from a member of a generic class or method?
Or do you need help with writing a unit test for an action? Then: How to unit test an ActionResult that returns a ContentResult?
Testing with Nunit, it usually looks like this when testing search results:
[Test]
public void Search_ShouldReturnAListOfOrders()
{
var result = _controller.Search("searchParameter") as MyViewModel ;
Assert.That(result, Is.Not.Null);
Assert.That(result.SearchResults, Is.Not.Null);
Assert.That(result.SearchResults.Count, Is.GreaterThan(0));
}
I am setting up a Mock as shown below. It is passed into the constructor of the target. The target has a Decrypt method that is called twice within the lifetime of the target. Each time the Decrypt method is called, it Disposes of the certificate that is "newed" up in the Setup. However, when calling the Decrypt object the second time, I am getting an ObjectDisposed method upon attempting the decryption. If I replace this Mock with a Fake implementation of ICertificateHelperAdapter that calls GetCertificate(), then the second call to Decrypt works properly.
I am deducing that when I use the Mock, it is not returning me a new instance of the object on subsequent calls to GetCertificate. Is this by design?
private Mock<ICertificateHelperAdapter> GetCertificateHelperAdapter()
{
Mock<ICertificateHelperAdapter> certificateHelper = new Mock<ICertificateHelperAdapter>();
certificateHelper.Setup(
ch => ch.GetCertificate(CertStoreName.My, StoreLocation.LocalMachine, It.IsAny<string>())).Returns(this.GetCertificate()).Verifiable();
return certificateHelper;
}
private X509Certificate2 GetCertificate()
{
return new X509Certificate2(Environment.CurrentDirectory + "\\" + "azureconfig.pfx", "dingos");
}
The different overloads of Returns<T> behaves differently:
The one with T Returns<T>(T value) what you are using is always returning the same instance.
But there is a lazy version which uses Func<T>. They are looks like T Returns<T>(Func<T> value) and they will evaluate each time the parameter function when the setup method is called.
Sample from the Moq site:
// lazy evaluating return value
mock.Setup(foo => foo.GetCount()).Returns(() => count);
Change your setup to:
certificateHelper.Setup(ch =>
ch.GetCertificate(CertStoreName.My, StoreLocation.LocalMachine, It.IsAny<string>()))
.Returns(() => this.GetCertificate()).Verifiable(); //note the lambda in Returns
And it will call your GetCertificate() twice.
Seems like Moq is caching data I set up as return. When I do this:
var service = new Mock<AlbumService>();
service.Setup(x => x.CreateOne()).Returns(new AlbumService().CreateOne());
it returns the same object even thought AlbumService.CreateOne() returns new Album instance.
Is it possible to make Moq call the Returns Action every time I access CreateOne() ?
This ought to help:
var service = new Mock<AlbumService>();
service.Setup(x => x.CreateOne()).Returns(() => new AlbumService().CreateOne());
To elaborate, the Returns method accepts an object of the return type or a delegate that will evaluate to the return type. The delegate is invoked whenever the mocked method is invoked.