I'm using PHPUnit 3.4.14 and I'm trying to add a Listener.
I wrote a simple one:
class My_Test_Listener implements PHPUnit_Framework_TestListener
{
public function addError(PHPUnit_Framework_Test $test, Exception $e, $time)
{
...
I declared it in my phpunit.xml file:
<phpunit bootstrap="./bootstrap.php">
<testsuites>
<testsuite name="auth">
<directory>./library/Ademe/Auth</directory>
</testsuite>
</testsuites>
<listeners>
<listener class="Listener" file="./library/My/Test/Listener.php">
</listener>
</listeners>
</phpunit>
My class is loaded (if I omit to implement one of the method, it says so in the logs), but I never go inside thoses methods. I tried this for instance :
public function startTestSuite(PHPUnit_Framework_TestSuite $suite)
{
die('startTestSuite');
}
Do you have any idea of what could be missing?
Thanks!
OK I got it, the class name was wrong, allthough no error was reported. I should have done this instead:
<phpunit bootstrap="./bootstrap.php">
<testsuites>
<testsuite name="auth">
<directory>./library/Ademe/Auth</directory>
</testsuite>
</testsuites>
<listeners>
<listener class="My_Test_Listener" file="./library/My/Test/Listener.php">
</listener>
</listeners>
</phpunit>
I had the same error but the listener worked only when I used
<listener class="\Name\Space\MyTestListeners" ></listener>
Related
I would like to test my DAO service.
The problem is that nothing append when I execute my test. No test is executed.
But I'm sur that the config file phpunit.xml.dist is ok, beause if I make a mistake in the "use" line for exemple, the test show me the errors.
So I need your help..
My first test :
namespace RepositoryBundle\Tests\DAO;
use RepositoryBundle\Entity\User;
use RepositoryBundle\Enum\RoleEnum;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
class UserDAOTest extends KernelTestCase
{
private $userDAO;
private $logger;
public function setUp()
{
self::bootKernel();
$this->userDAO = static::$kernel->getContainer()->get('repository.userDAO');
$this->logger = static::$kernel->getContainer()->get('logger');
$logger->notice('Show the log'); // Nothing is in my console.. (I configure Monolog to display in the console)
}
public function testTRUC()
{
//Stupid test but not executed !!!???
$i = 1;
$this->assertTrue($i == 1);
}
public function testCreate()
{
//Real test but not executed !!!???
$user1 = new User();
$user1->setName("TestName");
$user1->setEmail("TestEmail");
$user1->setPassword("TestPassword");
$user1->setMemberNumber(12345);
$user1->setAdmin(true);
$user1->setRole(RoleEnum::User);
$user1 = $UserDAO->save($user1);
$this->assertTrue($user1->getId() > 0);
$this->assertEquals("TestName", $user1->getName());
$this->assertEquals("TestEmail", $user1->getEmail());
$this->assertEquals("TestPassword", $user1->getPassword());
$this->assertEquals(12345, $user1->getMemberNumber());
$this->assertEquals(true, $user1->isAdmin());
$this->assertEquals(RoleEnum::User, $user1->getRole());
}
phpunit.xml.dist
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="phpunit.xsd"
bootstrap="bootstrap.php.cache"
backupGlobals="false"
verbose="true">
<testsuites>
<testsuite name="Project Test Suite">
<directory>../src/*Bundle/Tests</directory>
</testsuite>
</testsuites>
<php>
<const name="PHPUNIT_TESTSUITE" value="true"/>
</php>
</phpunit>
When I execute the command :
A screen of the console
Thanks for your help. I'm new with Symfony and PHPUnit and I lost a lot of time with this kind of problems..
Please correct me if I'm wrong, but your test is located in src\RepositoryBundle\Tests\DAO and you are executing phpunit on folder app...
Try phpunit(Edit of course c option requires an argument :/) and it should work.
You configuration is configured to look up '../src/*Bundle/Tests'. If you provide the app folder as the place to to look up test, then your configuration won't be considered.
My config is a bean that I inject in my code wherever I need it. However, when injected, I get a new instance of the bean instead of the one from the session.
My bean:
#Named
#SessionScoped
public class TestModel implements Serializable {
private static final long serialVersionUID = 4873651498076344849L;
private String version;
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
public void changeVersion() {
this.version = "Version 2";
System.out.println("New version : " + version + ", Object : " + this);
}
}
When injected in different classes, all occurences are different instances.
When annotating the bean with #ApplicationScoped, it is the same instance.
I do need the bean to be #SessionScoped since every user should have his own config.
The WebApp is running on TomEE 1.7.4
UPDATE: I created a new project to test it, and the SessionScope works. I now need to find out what is wrong with my current project in order to fix it.
Facets:
CDI 1.0
Dynamic Web Module 3.0
Java 1.8
JSF 2.2 (MyFaces impl from TomEE)
JPA 2.1
Web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>Project</display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<context-param>
<description>State saving method: 'client' or 'server' (=default). See JSF Specification 2.5.2</description>
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>client</param-value>
</context-param>
<context-param>
<param-name>javax.servlet.jsp.jstl.fmt.localizationContext</param-name>
<param-value>resources.application</param-value>
</context-param>
<context-param>
<param-name>primefaces.THEME</param-name>
<param-value>omega</param-value>
</context-param>
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>
<context-param>
<param-name>javax.faces.FACELETS_SKIP_COMMENTS</param-name>
<param-value>true</param-value>
</context-param>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
</web-app>
faces-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<faces-config
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd"
version="2.2">
</faces-config>
beans.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
version="1.1" bean-discovery-mode="annotated">
</beans>
Any ideas ?
Looks like your test doesn't work:
testModel object = model.TestModel#689a6064
New version : Version 2, Object : model.TestModel#61606aa6
So you update an instance which is not the same as the one linked to the session (another request not reusing the same session I'd say)
You are doing it right. That is, from CDI perspective, you made no mistake and what you want is perfectly legit and should work (assuming you solved the problem of multiple sessions, which you did).
I just tried this with my own piece of code and it works as expected. You can check it on GitHub. The sample is more or less identical to yours.
However, I am running Wildfly 10 and therefore Weld 2.3 which comes with it (Weld being a reference impl of CDI). While you are running TomEE which contains OpenWebBeans (another CDI implementation).
To me it seems like you either missed some TomEE/OWB specific configuration (unrealistic scenario) or, more likely, you found a bug. In any case, if I were you, I would try asking on their forums or creating an issue in their tracking system because, once again, there is imho nothing wrong with your bean/servlet setup.
We have #SessionScope annotation in both JSF & CDI. Please review whether the annotation you are using in your old project is from JSF or from CDI.
Find more on the difference between the annotation from JSF & CDI
I have a lot of tests that require a particular mock object to be created. So, here is what I've done:
namespace AppBundle\Tests\Services\Terminal;
use Mockery\Adapter\Phpunit\MockeryTestCase;
use AppBundle\Entity\Tunnel;
class TunnelBasedTestCase extends MockeryTestCase
{
/**
*
* #var Tunnel
*/
protected $tunnel;
protected function setup()
{
$tunnel = new Tunnel();
$tunnel->setName('B9')
->setIp('192.168.2.52')
->setUsername('username')
->setPassword('password')
->setSign('sign')
->setStatus('open');
$this->tunnel = $tunnel;
}
}
However, the problem is that now PHPUnit tries to run this test, which is only meant to prevent me from copy-pasting the setup() function. I don't want to skip it, because I want to get a completely green test result instead of getting something like:
....S.....
Or this:
....I.....
Here is my PHPUnit configuration that also fails to do this:
<testsuites>
<testsuite name="Project Test Suite">
<directory>../src/*/*Bundle/Tests</directory>
<directory>../src/*/Bundle/*Bundle/Tests</directory>
<directory>../src/*Bundle/Tests</directory>
<exclude>../src/AppBundle/Tests/Services/Terminal/TunnelBasedTestCase.php</exclude>
</testsuite>
</testsuites>
How can I do this?
you can edit your phpunit.xml like this:
<?xml version="1.0" encoding="UTF-8"?>
<phpunit>
<testsuites>
<testsuite name="foo">
<directory>./tests/</directory>
<exclude>./tests/path/to/excluded/test.php</exclude>
^-------------
</testsuite>
</testsuites>
</phpunit>
You can also try to make a blacklist like this:
<filter>
<blacklist>
<file>../src/AppBundle/Tests/Services/Terminal/TunnelBasedTestCase.php</file>
</blacklist>
</filter>
We are using Tomcat 7.0.54.
The web.xml:
<context-param>
<param-name>log4jContextName</param-name>
<param-value>SabaLog4jContext</param-value>
</context-param>
There is sample servlet which starts on load
<servlet>
<servlet-name>startUp</servlet-name>
<servlet-class>foo.StartupServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
The StartupServlet simple as:
public class StartupServlet extends HttpServlet {
#Override
public void init() throws ServletException {
getServletContext().setAttribute("test", "ATest");
super.init();
}
}
The log4j2 can not access the test attribute with ${web:attr.test} and I got the warning as:
INFO: org.apache.logging.log4j.web.WebLookup unable to resolve key 'test'
It seems that Log4j2 works fine but the problem is that it starts before my Startup. I tried to use a servletContextListener class but no luck.
I also tried to disable Log4jAutoInitialization in web.xml and manually start set them as below.
<listener>
<listener-class>org.apache.logging.log4j.web.Log4jServletContextListener</listener-class>
</listener>
<filter>
<filter-name>log4jServletFilter</filter-name>
<filter-class>org.apache.logging.log4j.web.Log4jServletFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>log4jServletFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
<dispatcher>INCLUDE</dispatcher>
<dispatcher>ERROR</dispatcher>
</filter-mapping>
But no luck:(
The log4j2.xml is as below:
<property name="baseFolder">${web:rootDir}/../logs/${web:test}</property>
So how can setup my web.xml so that my code execute before Log4j context.
The web.xml also contains spring Listeners as:
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
First, make sure Tomcat is configured to provide the functionality of a servlet 3.0 container in your web.xml file:
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
You'll want the 3.0 functionality so you can specify the order in which the servlets are loaded. Then you'll want to have your own ServletContainerInitializer to initialize the ServletContext attributes. Here's an snippet of one of mine:
/* Initializer that is configured, via web.xml, to initialize before Log4j2's initializer. This gives us the
* opportunity to set some servlet context attributes that Log4j2 will use when it eventually initializes.
*/
public class BitColdHardCashContainerInitializer implements ServletContainerInitializer {
#Override
public void onStartup(final Set<Class<?>> classes, final ServletContext servletContext) throws ServletException {
if (servletContext.getMajorVersion() > 2) {
servletContext.log("BitColdHardCashContainerInitializer starting up in Servlet 3.0+ environment.");
}
// Set the webapp.name attribute so that Log4j2 may use it to create a path for log files.
servletContext.setAttribute("webapp.name", servletContext.getContextPath().replaceAll("/", "").trim());
Next, you want your ServerContainerInitializer to run before Log4j2's. In your web.xml, give your servlet a name:
<absolute-ordering>
<name>BitColdHardCash</name>
<others/>
</absolute-ordering>
This needs to be be specified before the <servlet> element.
Create a web-fragment.xml file:
<web-fragment xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-fragment_3_0.xsd"
version="3.0" metadata-complete="true">
<name>BitColdHardCash</name>
<distributable />
<ordering>
<before>
<others />
</before>
</ordering>
</web-fragment>
This tells Tomcat to initialize your ServletContainerInitializer first, before anything else, including Log4j2's. This goes in the META-INF directory.
That should do it. One more thing to check would be your catalina.properties file. You are using a version of Tomcat that fixes a bug regarding the calling of ServletContextInitializers. I'm not sure if the bug was in Tomcat source code or in the default supplied catalina.properties file. In the event you are using a catalina.properties file that pre-dates the fix, just crack it open an ensure that log4j*.jar is not included in the list of files specified for the tomcat.util.scan.DefaultJarScanner.jarsToSkip property.
I want to use Spring BlazeDS Integration.
I write them like this.
[web.xml]
<servlet>
<servlet-name>flex</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/classes/applicationContext.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>flex</servlet-name>
<url-pattern>/messagebroker/*</url-pattern>
</servlet-mapping>
[WEB-INF/classes/applicationContext.xml]
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:flex="http://www.springframework.org/schema/flex"
xsi:schemaLocation="
http://www.springframework.org/schema/flex
http://www.springframework.org/schema/flex/spring-flex-1.0.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<flex:message-broker/>
<bean id="hogeService" class="hoge.HogeServiceImpl">
<flex:remoting-destination />
</bean>
</beans>
[WEB-INF/flex/services-config.xml]
<services-config>
<services>
<default-channels>
<channel ref="my-amf"/>
</default-channels>
</services>
<channels>
<channel-definition id="my-amf" class="mx.messaging.channels.AMFChannel">
<endpoint url="http://{server.name}:{server.port}/{context.root}/messagebroker/amf" class="flex.messaging.endpoints.AMFEndpoint"/>
</channel-definition>
</services-config>
So, I call "hogeService" from Flex application like this.
var ro:RemoteObject = new RemoteObject();
ro.destination = "hogeService";
ro.hoge(); // HogeServiceImpl class has "hoge" method with no arguments.
Then, I got an error message like this.
[RPC Fault faultString="[MessagingError message='Destination 'hogeService' either does not exist or the destination has no channels defined (and the application does not define any default channels.)']" faultCode="InvokeFailed" faultDetail="メッセージ送信先への接続を確立できませんでした。"]
Why do I get this error message ?
And please tell me any solutions..
Make sure you have have your services-config.xml also passed to the flex compiler (compc or mxmlc) as the flag compiler.services.
Alternatively, you can let the RemoteObject build the channel (which then decouples the client and the server config completely), like so:
var ro:RemoteObject = RemoteObject();
ro.endpoint = "http://{server.name}:{server.port}/{context.root}/messagebroker/amf"; // this internally constructs an AMFChannel or SecuredAMFChannel depending on the protocol
ro.hoge();
With the latest versions of the Spring BlazeDS integration you just need to add a little something to your Spring dispatcher in order for things to work, though I believe you still need all the services-config.xml etc for Flex itself.
<flex:message-broker>
<flex:message-service default-channels="amf"/>
</flex:message-broker>
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<value>
/*=_messageBroker
</value>
</property>
</bean>
<bean class="org.springframework.flex.servlet.MessageBrokerHandlerAdapter"/>