Testing of static methods with PHPUnit - static

I want to test a method. This method used the static method verifyPassword() in an abstract class.
class Authentication {
...
public function onUserAuthenticate($credentials) {
….
$checkedIn = UHelper::verifyPassword($credentials);
…
}
Now I created a mock object in my test method, because I want not test the verifyPassword() with this test.
class AuthenticationTest {
..
public function testonUserAuthenticate {
...
$uhelper = $this->getMockForAbstractClass(\UHelper::class);
$uhelper->expects($this->any())
->method('verifyPassword')
->with($mypassword)
->will($this->returnValue(true));
$this->class = new \Authentication();
$this->class->onUserAuthenticate($credentials);
..
}
How can I accomplish, that my mock object is used in the test method when I run $this->class->onUserAuthenticate($credentials) ?
verifyPassword is a call to a static methode in the abstract class UHelper, so I do not have a setUHelper method anywhere.
hat I'm trying to do is make variable class Authentication in ther call of the method onUserAuthenticate use the stub $uhelper. That is not answered in the related question.

Related

How to test a MessageBox in wpf?

I'm going to do some unit tests and I am struggling with a MessageBox. I have a MessageBox that is showing a text and an "Ok" button in my code. When I trying to unit test the method that contains the MessageBox.Show("Text"), it pops up in the unit test, too, and I have to click "Ok" before it can pass through, which is a bad.
Does anyone know how to go around it? I think I need some kind of code that fakes this MessageBox and clicking "Ok", but I dont know how to do this. I'm a junior programmer, so please explain it as easy as you can ;) and gladly with some code examples.
This is my code for the MessageBox:
public void GetPopUpWithErrorMessage()
{
MessageBox.Show("Error Message", "text",
MessageBoxButton.OK);
}
Edit
I just realised that Fluent Assertions is used in the project. Does anyone know how to implement that in the test code? is it the same way as #thatguy showed?
You have to create a service that implements an interface that you can mock in your tests.
public interface IMessageBoxService
{
void ShowMessageBox(string title, string message);
}
public class MessageBoxService : IMessageBoxService
{
public void ShowMessageBox(string title, string message)
{
MessageBox.Show(message, title, MessageBoxButton.OK);
}
}
In the class where you use it, you would pass this service by its interface, e.g. in the constructor, so the class only knows its contract, but not its implementation.
public class MyClass
{
private IMessageBoxService _messageBoxService;
public MyClass(IMessageBoxService messageBoxService)
{
_messageBoxService = messageBoxService;
}
public void GetPopUpWithErrorMessage()
{
_messageBoxService.ShowMessageBox("text", "Error Message");
}
}
In the test class, you need to use a mocking framework like Moq that creates a mock object from an interface, which is just a stub that you can use to inject the behavior for any method or property that you use in your test.
In this example using NUnit and Moq, messageBoxService is created as a mock object that implements the IMessageBoxService interface. All methods do nothing unless you specify what they should do or return via Setup, but that is another topic. The last line shows how you could check if a sepcific method on the mock was invoked during the test.
[TestFixture]
public class MyClassTest
{
[Test]
public void MyTest()
{
var messageBoxService = Mock.Of<IMessageBoxService>();
var myClass = new MyClass(messageBoxService);
// ...your test code.
// Checks if the "ShowMessageBox" method in the service was called with any strings
Mock.Get(messageBoxService).Verify(mock => mock.ShowMessageBox(It.IsAny<string>(), It.IsAny<string>()));
}
}
Creating a service and an interface is not just useful for mocking, but also for separating view and logic, as you can extract the calling of a message box to a service which has an implementation hidden behind an interface. Moreover you can easily implement dependency injection via constructors.

mockStatic: mock java.lang with PowerMock

I am trying to mock MBeanServer with Mockito, but my attempts fails.
#Test
public void testGetAllCacheProperties() {
mockStatic(ManagementFactory.class);
MBeanServer server = MBeanServerFactory.newMBeanServer();
ObjectInstance inst = server.registerMBean(new MyBeanService(), ObjectName.getInstance(SERVICE_NAME));
given(ManagementFactory.getPlatformMBeanServer()).willReturn(server);
}
I suppose to inject my mock into method that normally runs on jBoss AS 7:
#GET
public Response getAllProperties() {
MBeanServer platformMBeanServer = ManagementFactory.getPlatformMBeanServer();
But it fails with exception:
org.mockito.exceptions.misusing.WrongTypeOfReturnValue:
JmxMBeanServer cannot be returned by getPlatformMBeanServer()
getPlatformMBeanServer() should return MBeanServer
Update
When I try
PowerMockito.doReturn(server).when(ManagementFactory.class, "getPlatformMBeanServer");
I get exception:
java.lang.LinkageError: loader constraint violation: when resolving method "java.lang.management.ManagementFactory.getPlatformMBeanServer()Ljavax/management/MBeanServer;" the class loader (instance of org/powermock/core/classloader/MockClassLoader) of the current class, my_package_for_test_class.TestClass, and the class loader (instance of <bootloader>) for the method's defining class, java/lang/management/ManagementFactory, have different Class objects for the type javax/management/MBeanServer used in the signature
There is not possible to mock static from java.lang package, since PowerMock tries to change bite code and bite code of java.lang classes
obviously protected from modifications.
There is work around suggested by Johan Haleby.
You have to create wrapper class:
public class JmxUtils {
public static MBeanServer getPlatformMbeanServer() {
return ManagementFactory.getPlatformMBeanServer();
}
}
Then test will look like this
#RunWith(PowerMockRunner.class)
#PrepareForTest(JmxUtils.class)
public class CacheControllerTest {
//.. preconditions
given(JmxUtils.getPlatformMbeanServer()).willReturn(server);

How to load a component in console/shell

In CakePHP, how do I load a component in a shell?
To use a component in a controller, you include an array of components in a property called $components. That doesn't work for my Shell. Neither does the "on-the-fly" loading suggested in the documentation.
class MakePdfsShell extends Shell {
public $components = array('Document'); // <- this doesn't work
public function main()
{
$this->Document = $this->Components->load('Document'); // <- this doesnt work either
$this->Document->generate(); // <- this is what I want to do
}
...
I have some xml utilities that I use across some of my controllers. One of the controller launches a heavy task via the cake console, so that it can quietly run in the background via PHP CLI, while the user's request is immediately completed (once the task done, it will e-mail the results to the user).
The xml utilities are generic enough to be used in controller and shell, are too specific to the application to warrant them vendor status. The offered solution with the Lib folder does not work as in CakePhp v3 there seems to be no Lib folder.
After some quite some time spent, I managed to load my controller component to the shell task. Here is how to:
namespace App\Shell;
use Cake\Console\Shell;
use Cake\Core\App;
use Cake\Controller\Component;
use Cake\Controller\ComponentRegistry;
use App\Controller\Component\XmlUtilitiesComponent; // <- resides in your app's src/Controller/Component folder
class XmlCheckShell extends Shell
{
public function initialize() {
$this->Utilities = new XmlUtilitiesComponent(new ComponentRegistry());
}
...
$this->Utilities can now be used across my entire shell class.
You simply don't.
If you think you have to load a component in shell your application architecture is bad designed and should be refactored.
Technically it is possible but it doesn't make sense and can have pretty nasty side effects. Components are not made to run outside of the scope of a request. A component is thought to run within the scope of a HTTP request and a controller - which is obviously not present in a shell.
Putting things in the right place
Why does XML manipulation stuff have to go into a component? This is simply the wrong place. This should go into a class, maybe App\Utility\XmlUtils for example and have no dependencies at all to the request nor controller.
The logic is properly decoupled then and can be used in other places that need it. Also if you get incoming XML the right place to do this manipulation (by using your utility class) would be inside the model layer, not the controller.
You want to learn about Separation of Concerns and tight coupling
Because you've gone just against both principles.
https://en.wikipedia.org/wiki/Separation_of_concerns
What is the difference between loose coupling and tight coupling in the object oriented paradigm?
Search before asking
You could have tried to search via Google or on SO you would have found one of these:
using components in Cakephp 2+ Shell
CakePHP using Email component from Shell cronjob
Using a plugin component from shell class in cakephp 2.0.2
...
Be aware that some of them might encourage bad practice. I haven't checked them all.
I assume that you have a component named YourComponent:
<?php
App::uses('Component', 'Controller');
class YourComponent extends Component {
public function testMe() {
return 'success';
}
}
- with cake 2., you can load your component like this
App::uses('ComponentCollection', 'Controller');
App::uses('YourComponent', 'Controller/Component');
class YourShell extends AppShell {
public function startup() {
$collection = new ComponentCollection();
$this->yourComponent = $collection->load('Your');
}
public function main() {
$this->yourComponent->testMe();
}
}
- with cake 3. you can load your component like this
<?php
namespace App\Shell;
use App\Controller\Component\YourComponent;
use Cake\Console\Shell;
use Cake\Controller\ComponentRegistry;
class YourShell extends Shell {
public function initialize() {
parent::initialize();
$this->yourComponent = new YourComponent(new ComponentRegistry(), []);
}
public function main() {
$pages = $this->yourComponent->testMe();
}
}
If you are trying to access a custom XyzComponent from a shell, then you probably have commonly-useful functionality there. The right place for commonly-useful functionality (that is also accessible from shells) is in /Lib/.
You can just move your old XyzComponent class from /Controller/Component/XyzComponent.php to /Lib/Xyz/Xyz.php. (You should rename your class to remove the "Component" suffix, e.g., "XyzComponent" becomes "Xyz".)
To access the new location, in your controller, remove 'Xyz' from your class::$components array. At the top of your controller file, add
App::uses('Xyz', 'Xyz'); // that's ('ClassName', 'folder_under_/Lib/')
Now you just need to instantiate the class. In your method you can do $this->Xyz = new Xyz(); Now you're using the same code, but it can also be accessed from your Shell.
//TestShell.php
class TestShell extends AppShell{
public function test(){
//to load a component in dis function
App::import('Component', 'CsvImporter');
$CsvImporter = new CsvImporterComponent();
$data = $CsvImporter->get();
}
}
//CsvImporterComponent.php
App::uses('Component', 'Controller');
class CsvImporterComponent extends Component {
function get(){
//your code
}
}

Rhino mocks unit test method args

I am new to rhino mocks and unit testing in general. I am starting to write some tests for my wpf mvvm app. Here is a sample scenario I am trying to test:
The view model:
List<DataItems> _theData = new List<DataItems>();
public MyViewModel(IServer server)
{
_server = server;
InitializeData();
}
private void InitializeData()
{
_server.GetData(MyCallback);
}
private void MyCallback()
{
_theData = _server.TheData;
}
public List<DataItems> VMData
{
get
{
return _theData;
}
}
Server:
public List<DataItems> TheData
{
get
{
return _cachedData;
}
}
public void GetData(Action callBack)
{
//Populate cached data
...
if(callBack != null)
{
callBack();
}
}
In my test, I want to verify that viewModel.VMData.Count == server.TheData.Count. I tried using rhino mocks to stub the server, pre-poulating TheData with some values. The I called the view model constructor, and then tried to compare the counts.
My problem is that I do not know how to get my server to actually call back into my view model. After the vm constructor is called, InitializeData() is called as expected but the stub server's GetData call is not made.
How can I make this simple test work?
if you are stubbing IServer and expecting that the calling a method on the stub will invoke the implementation in your concrete class, that is your misconception. the GetData method on the stub instance will only return what you tell it to, and not execute any code in the concrete dependency. remember that the only thing your stub IServer object has in common with your concrete implemetation of IServer is that they both implement IServer. expecting that the side effects in the method in your concrete implemenation will happen when calling the method on the stub is just faulty.
as to how to make it work: there's not really a good way to do this test as you are stating with the design of these classes as is. you are trying to test that a side effect occurred in the dependency that you are stubbing out of participation. to really test what you want here and if you want to keep these classes with this relationship, i'd suggest that you don't mock server at all and use the real object. redesign the server so that it depends on another component that loads from the cache so you can stub that thing instead.

Apex error: "Save error: Method does not exist or incorrect signature"

I'm currently learning apex (using the Force.com IDE), and I'm running into some trouble when writing a test for a custom controller.
The controller class is as follows:
public with sharing class CustomController {
private List<TestObject__c> objects;
public CustomController() {
objects = [SELECT id, name FROM TestObject__c];
}
public List<TestObject__c> getObjects() {
return objects;
}
}
and the test class is:
#isTest
private class ControllerTest {
static testMethod void customControllerTest() {
CustomController controller = new CustomController();
System.assertNotEquals(controller, null);
List<TestObject__c> objects;
objects = controller.getObjects();
System.assertNotEquals(objects, null);
}
}
On the objects = controller.getObjects(); line I'm getting an error which says:
Save error: Method does not exist or incorrect signature: [CustomController].getObjects()
Anyone have an idea as to why I'm getting this error?
A nice shorthand:
public List<TestObject__c> objects {get; private set;}
It creates the getter/setter for you and looks cleaner imo. As for your current issue, yes - it's hard saving code directly into production - especially with test classes in separate files.
Best to do this in a sandbox/dev org then deploy to production (deploy to server - Force.com IDE). But if you must save directly into production then I'd combine test methods with your class. But in the long run, having #test atop a dedicated test class is the way to go. It won't consume your valuable resources this way.

Resources