Why does class constructor get called for the second time after SUBMIT? - unit-testing

I have the following global class which is supposed to hold a reference to IF_OSQL_TEST_ENVIRONMENT as a static attribute.
CLASS zcl_static_holder DEFINITION
PUBLIC
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
CLASS-DATA sr_osql_test_environment TYPE REF TO if_osql_test_environment .
CLASS-METHODS class_constructor .
CLASS-METHODS set_osql_test_environment
IMPORTING
!ir_osql_test_environment TYPE REF TO if_osql_test_environment .
PROTECTED SECTION.
PRIVATE SECTION.
ENDCLASS.
CLASS zcl_static_holder IMPLEMENTATION.
METHOD class_constructor.
BREAK-POINT.
ENDMETHOD.
METHOD set_osql_test_environment.
sr_osql_test_environment = ir_osql_test_environment.
ENDMETHOD.
ENDCLASS.
Now I set this static attribute in a unit test in the following program. The class constructor of the above class gets called before the static attribute is initialised through the setter. However after sumbitting the report the class constructor is called for the second time and the static attribute of course is not set anymore.
REPORT zsubmit_with_static_holder.
CLASS lcl_test DEFINITION FINAL FOR TESTING
RISK LEVEL HARMLESS DURATION SHORT.
PUBLIC SECTION.
METHODS:
test FOR TESTING.
ENDCLASS.
CLASS lcl_test IMPLEMENTATION.
METHOD test.
DATA(lr_osql_test_environment) = cl_osql_test_environment=>create(
VALUE #( ( 'T100' ) )
).
zcl_static_holder=>set_osql_test_environment( lr_osql_test_environment ).
SUBMIT zsubmit_with_static_holder
AND RETURN.
ENDMETHOD.
ENDCLASS.
START-OF-SELECTION.
IF zcl_static_holder=>sr_osql_test_environment IS NOT BOUND.
WRITE / 'Not bound.'.
ENDIF.
SELECT COUNT( * ) FROM t100.
IF sy-subrc <> 0.
WRITE / 'No entries. Table mocked!'.
ENDIF.
Why is so? How can I get it to work? I found something about database LUWs and SAP LUWs and that it could be solved by shared memory object which on the other hand look very complex for such an easy usage in a unit test.

SUBMIT starts a new Internal Session and so all programs are loaded again.
Better move the code after start-of-selection in a class and call this class instead of using SUBMIT.
If you can't avoid SUBMIT, I think there's no solution, but who knows.

Related

How do I access an object's eigenclass in Crystal?

In Ruby, it's possible to access the eigenclass (or "singleton class") of an object by reopening it. This is particularly useful for defining "private class methods":
class Foo
class << self
private
def declarative_method_name
end
end
declarative_method_name
end
# Foo.declarative_method_name => ERROR!
However, in Crystal this is not syntax:
Syntax error in ./test.cr:2: expecting token 'CONST', not '<<'
class << self
^
Is there another (or indeed any) way to achieve this in Crystal currently?
There's no eigenclass, or more commonly called singleton class in Ruby these days (given there's Object#singleton_class), in Crystal.
However defining class methods and calling them on the class level is supported:
class Foo
private def self.declarative_method_name
puts "hey"
end
declarative_method_name
end
https://carc.in/#/r/1316
The def self. construct here is specialized by the compiler and there's no more general concept beneath it, yet.
How would you make a super classes' new method private while still allowing it's subclasses' to be public?
class Foo
private self.new; end
end
class Bar < Foo
end
Bar.new #=> error: private method 'new' called for Foo:Class
It's also worth noting here that unlike in Ruby, class variables don't transcend inheritance. In Ruby the following code has a strange side effect...
class Foo
##var = 'foo'
def var
##var
end
end
class Bar < Foo
##var = 'bar'
end
puts Foo.new.var
It'll return 'bar' despite the fact that we modified the class variable on Bar. In crystal it returns 'foo' meaning that another reason we'd access the eiganclass, to store and read class level state safely, isn't necessary in crystal, we can just use class variables.

Mocking DBSet, EF Model First

As said in the title, I follow Model First method. So my Model classes are Automatically generated. If I want mock the DBContext derived MyModelContainer which contain DBSets of entity classes. Read some where that in order to unit test, you need to change it to IDBSet. Whether its possible to do it especially in a class that gets auto generated when I do "Run Custom Tool" is one concern. But as of now I modified it.
But the real problem is: when I try to Stub MyModelContainer to return a mock generated from IDBSet. Rhino mock is firing an InvalidOperationException: "Invalid call, the last call has been used, or no call has been made(make sure that you are calling a virtual(C#)/Overridable(VB) method."
Here is my unit test code.
MyModelContainer dbMock = MockRepository.GenerateMock<MyModelContainer>();
IDBSet<Models.MyEntity> entityMock = MockRepository.GenerateMock<IDBSet<Models.MyEntity>>()
dbMock.Stub( x=>x.MyEntities ).Return( entityMock );
The last statement is triggering the exception. I tried using the fake implementation of IDBSet<> specified here, But no luck!
I use MVC 4, Rhino Mocks 3.6. Any help will be appreciated.
Update:
After some trials and research, I found a fix. I changed the code to:
MyModelContainer dbMock = MockRepository.GenerateMock<MyModelContainer>();
IDBSet<Models.MyEntity> entityMock = MockRepository.GenerateMock<IDBSet<Models.MyEntity>>()
//dbMock.Stub( x=>x.MyEntities ).Return( entityMock );
dbMock.MyEntities = entityMock;
Now the InvalidOperationException is gone.
The test fails only due to ExpectationViolationException which should be normal.
As for auto generated Model class, it is found out that editing the DbContext's T4 template (.tt extension) will do the trick. Thanks to Alan's Blog
But I want to know why the previous code didn't work. Anyone?
2 reasons are possible here:
MyEntites property of MyModelContainer is not virtual.
In that case Rhino Mock can't stub this property at all. Then dbMock.Stub(x=>x.MyEntities) will fail.
MyEntites property is virtual, but has both public getter and public setter.
Then notation dbMock.Stub(x=>x.MyEntities).Return(entityMock) is not allowed. You can see explanation e.g. here.
In both cases the right fix is exactly what you did: use dbMock.MyEntities = entityMock instead of dbMock.Stub(x=>x.MyEntities).Return(entityMock).
Here is an extension method for Substituting IDbSet (with NSubstitute) to return an IQueryable
public static DbSet<T> FakeDbSet<T>(this IQueryable<T> queryable) where T : class
{
DbSet<T> fakeDbSet = Substitute.For<DbSet<T>, IQueryable<T>>();
((IQueryable<T>)fakeDbSet).Provider.Returns(queryable.Provider);
((IQueryable<T>)fakeDbSet).Expression.Returns(queryable.Expression);
((IQueryable<T>)fakeDbSet).ElementType.Returns(queryable.ElementType);
((IQueryable<T>)fakeDbSet).GetEnumerator().Returns(queryable.GetEnumerator());
fakeDbSet.AsNoTracking().Returns(fakeDbSet);
return fakeDbSet;
}
Then you can now stub the DbContext like this:
var db = NSubstitute.Substitute.For<DataContext>();
var fakeResult = emptyCustomers.FakeDbSet();
db.Customers.Returns(fakeResult);
Here is an extension method for Stubing (with RhinoMocks) IDbSet to return an IQueryable
public static class RhinoExtensions
{
public static IDbSet<T> MockToDbSet<T>(this IQueryable<T> queryable) where T : class
{
IDbSet<T> mockDbSet = MockRepository.GenerateMock<IDbSet<T>>();
mockDbSet.Stub(m => m.Provider).Return(queryable.Provider);
mockDbSet.Stub(m => m.Expression).Return(queryable.Expression);
mockDbSet.Stub(m => m.ElementType).Return(queryable.ElementType);
mockDbSet.Stub(m => m.GetEnumerator()).Return(queryable.GetEnumerator());
return mockDbSet;
}
}
Then you can now stub the DbContext like this:
_db.Stub(p => p.Customers).Return(fakeCustomers.MockToDbSet());

Codeigniter always load in controller

I`m from Russia, so sorry for bad English.
I want to load template in every page in controller.
For example (library parser in autoload),
class Blog extends CI_Controller {
$header = array(
'header' => 'Welcome to my blog!'
);
$this->parser->parse('header', $header);
function index() {
...
echo "My text";
}
header.php:
<h1>{header}</h1>
<script>
alert("Welcome!");
</script>
But I get an PHP error:
syntax error, unexpected T_VARIABLE, expecting T_FUNCTION in line 6. Line 6:
$header = array(
How can I load header in every page? Thanks.
config.php:
$autoload['libraries'] = array('parser');
controller blog.php:
<?php
class Blog extends Controller {
function __construct()
{
parent::Controller();
$header = array('header' => 'Welcome to my blog!');
$this->parser->parse('header', $header);
}
function index()
{
echo "Мой текст";
}
}
?>
view header.php:
{header}
it works for me..
try calling the array with $this->header
Maybe it's a typing error but in the code from header.php you have typed {header} where I guess it should be {$header}
When loading class properties, like your $header above, php expects the property's visibility to be declared before the variable name. PHP5 has three visibility options: 'public', 'private', or 'protected'. I think this is why you are getting "unexpected T_VARIABLE". The difference between them are described at swik.net as:
To protect from accessibility pollution, PHP v5 introduces 3 prefixes for declaring class methods or variables: public, protected, and private.
Public methods and variables are accessible outside of the class. Protected are only accessible from inside of the class and inherited or parent classes. Private are only accessible from within the class itself.
try this: (I chose 'public' visibility, you can determine which is appropriate for your use)
public $header = array('header'=>'Welcome to my blog");
Next, I think you should call your parser in a constructor, rather than outside of a class method.
function _construct(){
parent::_construct();
$this->parser->parse('header',$this->header);
}
The constructor will be called every time the class is instantiated, loading your parser library method along with it.
Update:
Your comment suggests that the parser isn't working like you expect. I assume you have placed
$this->parser->parse('header,$this->header);
in the constructor function like I suggested. If that isn't working, create a function with the same name as your class and put the parser in there, that function will load every time the class is called, similar to the constructor, but let's see if that does the trick. I suggest taking the parser library out of auto load until you've resolved your problem, just to simplify things.
function blog(){
$this->load->library('parser');
$this->parser->parse('header',$this->header);
}

Doctrine 2 self-referencing entity won't return the parent id

I've set up a self-referencing entity per the manual here:
http://www.google.com/url?sa=D&q=http://www.doctrine-project.org/docs/orm/2.0/en/reference/association-mapping.html%23one-to-many-self-referencing
My class is Page (instead of Category, like in the docs). In my entity
class I have a toArray() method that I've implemented that will give
me back the values of my member variables. For those fields that are
associations, I've made sure to grab the associated class object then
grab the id. I'm doing this to populate a form. Here is the code from
my toArray() method in my Page entity as well as my PageService
function to grab a Page object and my Page Controller code that calls
toArray() to populate my form.
http://pastie.org/1686419
As I say in the code comments, when the toArray() method is called in
the Page Controller, all values get populated except for parent id.
page_type is also a ManyToOne association and it gets populated no
problem. Explicitly grabbing the parent id from the Page object
outside of the toArray() method (in the Page Controller) does return
the parent id value. (See code.)
As a side note, I'm using __get() and __set() in my Page entity instead of full blown getters/setters.
I think it is because you are getting caught out by proxies. When you have an association in Doctrine 2, the related objects are not returned directly as objects, but as subclasses which do not fill their properties until a method is called (because of lazy loading to save database queries).
Since you are calling the property directly (with $this->parent->id) without invoking any method the object properties are all empty.
This page http://www.doctrine-project.org/docs/orm/2.0/en/tutorials/getting-started-xml-edition.html#a-first-prototype has a warning about this type of thing in the warning box. Although yours isn't a public property, you are accessing as though it were because that object is of the same class and the same problem is occuring.
Not sure of exactly what is causing your described behavior, but you're probably better anyway to have your toArray() method call getters/setters rather than having toArray() operate directly on the class properties. This will give you consistency so that if you implement custom getters for certain properties, you'll always get back the same result from toArray() and the getter.
A rough example:
<?php
/** #Entity */
class MyEntity {
// ....
/** #Column */
protected $foo;
public function setFoo($val)
{
$this->foo = $val;
}
public function getFoo()
{
return 'hello ' . $this->foo;
}
public function toArray()
{
$fields = array('foo');
$values = array();
foreach($fields as $field) {
$method = 'get' . ucfirst($field);
if (is_callable(array($this, $method)) {
$fields[$field] = $this->$method();
} else {
$fields[$field] = $this->$field;
}
}
return $fields;
}
}
Now you get the same result:
<?php
$e = new MyEntity;
$e->setFoo('world');
$e->getFoo(); // returns 'hello world'
$e->toArray(); // returns array('foo' => 'hello world')

MSTest, Accessors, Inheritance, and Private Members

I'm trying to write some tests for an MVC application we're developing. We have a BaseController class that contains the following:
public class BaseController : Controller
{
protected string UserRole { get; private set; }
We then have a controller that inherits from the BaseController:
public class CustomFieldController : BaseController
I've generated private accessors for both classes (just regenerated them a few minutes ago). In one of my unit tests for CustomFieldController I want to set the UserRole, so I've got the following code:
CustomFieldController controller = new CustomFieldController();
CustomFieldController_Accessor accessor = new CustomFieldController_Accessor(
new PrivateObject( controller, new PrivateType( typeof( BaseController ) ) ) );
accessor.UserRole = "OTHER";
Every time I try to run this test it throws an exception on the last line stating:
The member specified (CustomFieldEdit) could not be found. You might need to regenerate your private accessor, or the member may be private and defined on a base class. If the latter is true, you need to pass the type that defines the member into PrivateObject's constructor.
As far as I can tell, I've done what it says. Not only have I recently regenerated the private accessor, but I am passing the type that defines the member into PrivateObject's constructor.
Any thoughts as to what I'm missing here? I know I can make it work by taking the "private" off the property setter, but I'd rather not do that if I can avoid it (don't want subclass implementers thinking they can inject a value into that property).
CustomFieldController controller = new CustomFieldController();
var po = new PrivateObject( controller, new PrivateType( typeof( BaseController ) ) );
CustomFieldController_Accessor accessor = new CustomFieldController_Accessor( po );
po.SetFieldOrProperty("UserRole","OTHER");