spring-data-neo4j in "Advanced Mapping" mode - How can I read an entity-value without starting a transaction manually? - spring-data-neo4j

In my JavaEE7-project, I am using spring-data-neo4j standalone in "Advanced Mapping" mode (using spring-aspects). Everything works fine so far: CRUD on entities within a transaction, where the transaction is started manually or via #Transactional-annotation.
In my usecase, my view accesses an entity "directly":
// User
#NodeEntity
public class User {
private String firstName;
// getter, setter, ...
}
// SessionBean
#SessionScoped
#Named
public class SessionBean {
#Transactional
public User getUser() {
User user = ...;
System.out.println(user.getFirstName()); // (1) gives firstName-value.
return user;
}
}
// sometpl.xhtml
${sessionBean.user.firstName} // (2) gives "null".
Somehow, this behavior (difference between (1) and (2)) is wanted, as spring-data-neo4j supposes read-access only within a transaction.
But I want to have my usecase(2) working (returning the user's firstName, not "null"). Is there any way to achieve this? So let's say, starting transaction automatically in read-access-case? Implicit read-transactions-support?

My workaround:
Use a RequestScoped bean to start a transaction in "preRenderView" and to close this tx when the bean is destroyed.
This does not work on ajax-calls!
#Named
#RequestScoped
public class SpringDataNeo4jHelperBean {
#Inject
#Named
private Neo4jTemplate neoTemplate;
private Transaction tx;
#PreDestroy
public void finishTransaction() {
if (this.tx != null) {
this.tx.success();
this.tx.finish();
}
}
public void startReadOnlyTransaction() {
if (!this.neoTemplate.getGraphDatabase().transactionIsRunning()) {
this.tx = this.neoTemplate.getGraphDatabaseService().beginTx();
}
}
}
In some template, for example s.th. like a central layout.xhtml:
<f:metadata>
<f:event type="preRenderView" listener="#{springDataNeo4jHelperBean.startReadOnlyTransaction()}" />
</f:metadata>

Related

How to get db data back via repository service with MVC and Moq

I need to retrieve data from the db, via a service, in order to test captured data for structural validity.
i.e. The db data specifies the sizes of parts of a captured concatenated string, (in a certain order), which I mock. So no worries there.
But I don't want to mock the service's data.
I want to actually retrieve the db data, which can change/vary vastly for different clients, and different scenarios, or be changed regularly.
So, changing the mocked data for each scenario is not feasible.
The Service implements an interface and also injects the Data Access Layer's interface.
I do set 'CallBase' as true, but I'm not getting db Data back.
Please help.
Thanks
public interface I_PartDao
{
ExBool List(out List<GXL_PartSizes> _PartSizes);
}
public class GXL_PartSizes
{
public int? ID { get; set; }
public int? PartLength { get; set; }
public int? SortOrder { get; set; }
public GXL_PartSizes()
{
this.ID = null;
this.PartLength = null;
this.SortOrder = null;
}
}
// Service Layer
public interface I_PartBo
{
ExBool List(out List<GXL_PartSizes> _PartSizes);
}
public class PartBo : I_PartBo
{
// For the injection of the Dao services (Dao handles the Ado CRUD operations against MSSQL dbase)
private I_PartDao PartDao;
public PartBo(I_PartDao dao_Part)
{
this.PartDao = dao_Part ?? throw new ArgumentNullException("dao_Part");
}
public ExBool List(out List<GXL_PartSizes> _PartSizes)
{
return this.PartDao.List(out _PartSizes);
}
}
[TestClass]
public class GXL_ConcatenatedStructures_Test
{
ExBool result = new ExBool(); // A class to handle error messages and statuses
private List<GXL_PartSizes> partSizes;
[TestMethod]
public void Test_Part_1_Length_matches_dbStructure_for_part1()
{
// Arrange
var mockService = new Mock<I_PartBo>();
// This is retrieved from the data posted back to the controller,..but for here and now, just a local populated strign var
var concatenatedString_part1 = "ABC";
// Act
//mockService.CallBase = true;
mockService
.Setup(x => x.List(out partSizes))
.Returns(result);
// Assert
Assert.AreEqual(concatenatedString_part1, partSizes[0].PartLength);
}
}
I thought that there was a way to do what I wanted to, by using moq.
However,
by just using the normal concrete classes, as per the usual (sans DI) way, The db data is retrieved.
i.e.
NamespaceX.GLX_SetupDao dao = new NamespaceX.GLXSetupDao("data source=LAPTOP-a; Initial
Catalog=aaaa; Integrated Security=True;");
GLX_SetupBo boService = new GLX_SetupBo(dao);
result = boService.List(out List<GXL_PartSizes> sizes);

Unit testing a started Service which has a few fields injected into it?

I am a Dagger newbie.
TL;DR:
If an Android Service has any fields injected into it using Dagger, then in order to actually perform the injection, I need to have an instance of that Service.
In Robolectric tests, this corresponds to MyService service = Robolectric.buildService(MyService.class).get(). And then, objectGraph.inject(service);
However, rest of the code that actually starts MyService still uses context.startService(context, MyService.class);.
Question: What is the idiomatic way in Dagger to address this mismatch?
Let's say I have a Service as follows:
public class MyService {
#Inject Parser parser;
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
String data = intent.getStringExtra("data_to_be_parsed");
parser.parse(data);
}
}
Elsewhere in my code, I have an ApiClient class that does this:
public class ApiClient{
public static void parseInBackground(Context context, String data){
//This service does not have its fields injected
context.startService(new Intent(context, MyService.class).putExtra("data_to_be_parsed", data));
}
}
That parseInBackground method will be called from an Activity in response to user interaction.
Now, I'm following TDD and hence, I haven't yet written the Application Module for this. Here's the test module:
#Module(injects = MyService.class)
public class TestModule {
#Provides #Singleton Parser provideParser(){
return new MockParser();
}
}
And finally, the test case:
#RunWith(Robolectric.class)
public class ApiTest {
#Test
public void parseInBackground_ParsesCorrectly(){
//This service has its fields injected
MyService service = Robolectric.buildService(MyService.class).get();
ObjectGraph.create(new TestModule()).inject(service);
ApiClient.parseInBackground(Robolectric.application, "<user><name>droid</name></user>");
//Asserts here
}
}
As you can see, in the test, I retrieve an instance of the service and then inject the MockParser into it. However, the ApiClient class directly starts the service using an Intent. I don't have a chance to perform the injection.
I am aware that I can have MyService perform an injection on itself:
public void onCreate(){
ObjectGraph.create(new TestModule()).inject(this);
}
But then, I am hardcoding the TestModule here.
Is there an existing idiom in Dagger to set up dependencies for such situations?
It's the wrong way to hardcode your modules either in tests or in services. Better approach is to perform creation via your custom Application object which in turn will hold singleton ObjectGraph object. For example:
// in MyService class
#Override public void onCreate() {
super.onCreate();
MyApp.from(context).inject(this);
}
// in MyApp class
public static MyApp from(Context context) {
return (MyApp) context.getApplicationContext();
}
//...
private ObjectGraph objectGraph;
#Override public void onCreate() {
// Perform Injection
objectGraph = ObjectGraph.create(getModules());
objectGraph.inject(this);
}
public void inject(Object object) {
objectGraph.inject(object);
}
protected Object[] getModules() {
// return concrete modules based on build type or any other conditions.
}
Alternatively, you can refactor last method out into separate class and make different implementations for different flavors or build types. Also you may want to set overrides=true in your TestModule's annotation.

How to use Moq to Prove that the Method under test Calls another Method

I am working on a unit test of an instance method. The method happens to be an ASP.NET MVC 4 controller action, but I don't think that really matters much. We just found a bug in this method, and I'd like to use TDD to fix the bug and make sure it doesn't come back.
The method under test calls a service which returns an object. It then calls an internal method passing a string property of this object. The bug is that under some circumstances, the service returns null, causing the method under test to throw a NullReferenceException.
The controller uses dependency injection, so I have been able to mock the service client to have it return a null object. The problem is that I want to change the method under test so that when the service returns null, the internal method should be called with a default string value.
The only way I could think to do this is to use a mock for the class under test. I want to be able to assert, or Verify that this internal method has been called with the correct default value. When I try this, I get a MockException stating that the invocation was not performed on the mock. Yet I was able to debug the code and see the internal method being called, with the correct parameters.
What's the right way to prove that the method under test calls another method passing a particular parameter value?
I think there's a code smell here. The first question I'll ask myself in such a situation is, is the "internal" method really internal/ private to the controller under test. Is it the controller's responsibility to do the "internal" task? Should the controller change when the internal method's implementation changes? May be not.
In that case, I would pull out a new targeted class, which has a public method which does the stuff which was until now internal to the controller.
With this refactoring in place, I would use the callback mechanism of MOQ and assert the argument value.
So eventually, you will end up mocking two dependancies:
1. The external service
2. The new targeted class which has the controller's internal implementation
Now your controller is completely isolated and can be unit tested independently. Also, the "internal" implementation becomes unit testable and should have its own set of unit tests too.
So your code and test would look something like this:
public class ControllerUnderTest
{
private IExternalService Service { get; set; }
private NewFocusedClass NewFocusedClass { get; set; }
const string DefaultValue = "DefaultValue";
public ControllerUnderTest(IExternalService service, NewFocusedClass newFocusedClass)
{
Service = service;
NewFocusedClass = newFocusedClass;
}
public void MethodUnderTest()
{
var returnedValue = Service.ExternalMethod();
string valueToBePassed;
if (returnedValue == null)
{
valueToBePassed = DefaultValue;
}
else
{
valueToBePassed = returnedValue.StringProperty;
}
NewFocusedClass.FocusedBehvaior(valueToBePassed);
}
}
public interface IExternalService
{
ReturnClass ExternalMethod();
}
public class NewFocusedClass
{
public virtual void FocusedBehvaior(string param)
{
}
}
public class ReturnClass
{
public string StringProperty { get; set; }
}
[TestClass]
public class ControllerTests
{
[TestMethod]
public void TestMethod()
{
//Given
var mockService = new Mock<IExternalService>();
mockService.Setup(s => s.ExternalMethod()).Returns((ReturnClass)null);
var mockFocusedClass = new Mock<NewFocusedClass>();
var actualParam = string.Empty;
mockFocusedClass.Setup(x => x.FocusedBehvaior(It.IsAny<string>())).Callback<string>(param => actualParam = param);
//when
var controller = new ControllerUnderTest(mockService.Object, mockFocusedClass.Object);
controller.MethodUnderTest();
//then
Assert.AreEqual("DefaultValue", actualParam);
}
}
Edit: Based on the suggestion in the comments to use "verify" instead of callback.
Easier way to verify the parameter value is by using strict MOQ behavior and a verify call on the mock after system under test is executed.
Modified test could look like below:
[TestMethod]
public void TestMethod()
{
//Given
var mockService = new Mock<IExternalService>();
mockService.Setup(s => s.ExternalMethod()).Returns((ReturnClass)null);
var mockFocusedClass = new Mock<NewFocusedClass>(MockBehavior.Strict);
mockFocusedClass.Setup(x => x.FocusedBehvaior(It.Is<string>(s => s == "DefaultValue")));
//When
var controller = new ControllerUnderTest(mockService.Object, mockFocusedClass.Object);
controller.MethodUnderTest();
//Then
mockFocusedClass.Verify();
}
"The only way I could think to do this is to use a mock for the class under test."
I think you should not mock class under test. Mock only external dependencies your class under test has. What you could do is to create a testable-class. It would be a class which derives from your CUT and here you can catch the calls to the another method and verify it's parameter later. HTH
Testable class in the example is named MyTestableController
Another method is named InternalMethod.
Short example:
[TestClass]
public class Tests
{
[TestMethod]
public void MethodUnderTest_WhenServiceReturnsNull_CallsInternalMethodWithDefault()
{
// Arrange
Mock<IService> serviceStub = new Mock<IService>();
serviceStub.Setup(s => s.ServiceCall()).Returns((ReturnedFromService)null);
MyTestableController testedController = new MyTestableController(serviceStub.Object)
{
FakeInternalMethod = true
};
// Act
testedController.MethodUnderTest();
// Assert
Assert.AreEqual(testedController.SomeDefaultValue, testedController.FakeInternalMethodWasCalledWithThisParameter);
}
private class MyTestableController
: MyController
{
public bool FakeInternalMethod { get; set; }
public string FakeInternalMethodWasCalledWithThisParameter { get; set; }
public MyTestableController(IService service)
: base(service)
{ }
internal override void InternalMethod(string someProperty)
{
if (FakeInternalMethod)
FakeInternalMethodWasCalledWithThisParameter = someProperty;
else
base.InternalMethod(someProperty);
}
}
}
The CUT could look something like this:
public class MyController : Controller
{
private readonly IService _service;
public MyController(IService service)
{
_service = service;
}
public virtual string SomeDefaultValue { get { return "SomeDefaultValue"; }}
public EmptyResult MethodUnderTest()
{
// We just found a bug in this method ...
// The method under test calls a service which returns an object.
ReturnedFromService fromService = _service.ServiceCall();
// It then calls an internal method passing a string property of this object
string someStringProperty = fromService == null
? SomeDefaultValue
: fromService.SomeProperty;
InternalMethod(someStringProperty);
return new EmptyResult();
}
internal virtual void InternalMethod(string someProperty)
{
throw new NotImplementedException();
}
}

Why is AutoFixture Customization causing inherited properties to not be filled?

I wrote the following customization and have it applied as part of a composite on most of my tests. My entities have a read-only Id, but I'm using their SetId method in this customization to make sure all entities have some Id if they are transient (don't have an Id already).
public class SetEntityIdCustomization : ICustomization {
public void Customize(IFixture fixture) {
var engine = ((Fixture)fixture).Engine;
fixture.Customizations.Add(new Postprocessor(
engine, o => {
var entity = o as BaseEntity;
if (entity == null || !entity.IsTransient()) {
return;
}
entity.SetId(fixture.CreateAnonymous<Guid>());
}));
}
}
This has been working great, until I discovered a very odd thing today. If I feed a test one of my entities that directly inherits from BaseEntity, all is well and it's writeable properties are auto-filled. However, if I ask for an entity that inherits from something further down from BaseEntity, my customization prevents the properties from auto-filling.
The User entity in this test method is filled properly:
public class User : BaseEntity {
public string Email { get; set; }
public int CoolThings { get; set; }
}
...
[Theory, AutoDomainData]
public void SomeTest(User user, ...) {
// user.Email and user.CoolThings have auto-filled values, as expected.
...
}
However, the AwesomeUser entity in the following test does not get any of the same properties auto-filled.
public class AwesomeUser : User {
...
}
...
[Theory, AutoDomainData]
public void SomeOtherTest(AwesomeUser user, ...) {
// user.Email nor user.CoolThings have auto-filled values. What gives?
...
}
In both test cases, the Id property is auto-filled because of my customization. If I remove my customization, the SomeOtherTest's AwesomeUser instance gets its inherited properties auto-filled just fine. I must assume that my customization is what is messing things up.
Is there a better way to get all my BaseEntity instances to set their Id, or is there something else I'm missing with AutoFixture? I've applied my customization first, in the middle, and last, to no avail.
The solution provided above is a pretty clever attempt, but not something I've seen before. A more idiomatic solution would be something like this:
public void Customize(IFixture fixture)
{
fixture.Customizations.Add(
new FilteringSpecimenBuilder(
new Postprocessor(
new BaseEntityBuilder(
new ConstructorInvoker(
new ModestConstructorQuery())),
new AutoPropertiesCommand().Execute),
new BaseEntitySpecification()));
}
private class BaseEntityBuilder : ISpecimenBuilder
{
private readonly ISpecimenBuilder builder;
private readonly IRequestSpecification specification;
public BaseEntityBuilder(ISpecimenBuilder builder)
{
this.builder = builder;
this.specification = new BaseEntitySpecification();
}
public object Create(object request, ISpecimenContext context)
{
if (!this.specification.IsSatisfiedBy(request))
return new NoSpecimen(request);
var b = (BaseEntity)this.builder.Create(request, context);
b.SetId((Guid)context.Resolve(typeof(Guid)));
return b;
}
}
private class BaseEntitySpecification : IRequestSpecification
{
public bool IsSatisfiedBy(object request)
{
var t = request as Type;
if (t == null)
return false;
if (!typeof(BaseEntity).IsAssignableFrom(t))
return false;
return true;
}
}
As you can see, this isn't a simple one-liner, which is indicative of AutoFixture being a rather opinionated library. In this case, AutoFixture's opinion is:
Favor object composition over class inheritance.
-Design Patterns, p. 20
AutoFixture is first and foremost a TDD tool, and one of the main advantages of TDD is that it provides feedback about class design. In this case, the feedback is: Inheritance is awkward and troublesome. Reconsider the design.

How to make AfterBeanDiscovery get triggered in JUnit

I have the following four classes: DataConsumer, DataProducer, SomeQualifier, a META-INF/beans.xml and a test. The class files are coded as follows:
public class DataConsumer {
private boolean loaded = false;
#Inject
#SomeQualifier
private String someString;
public void afterBeanDiscovery(
#Observes final AfterBeanDiscovery afterBeanDiscovery,
final BeanManager manager) {
loaded = true;
}
public boolean getLoaded() {
return loaded;
}
public String sayHello() {
return someString;
}
}
public class DataProducer {
#Produces
#SomeQualifier
private final String sample = "sample";
}
public #interface SomeQualifier {
}
The unit test looks like this.
public class WeldTest {
#Test
public void testHelloWorld() {
final WeldContainer weld = new Weld().initialize();
final DataConsumer consumer = weld.instance()
.select(DataConsumer.class).get();
Assert.assertEquals("sample", consumer.sayHello());
Assert.assertTrue(consumer.getLoaded());
}
}
However, it is failing on the assertTrue with getLoaded() it appears that the #Observes does not get fired.
Take a look at arquillian: www.arquillian.org. It'll take care of all of this for you.
I found a similar question that had answered my question
CDI - Observing Container Events
Although I am unable to use DataConsumer as both an Extension and a CDI managed bean. So it needs a third class just to be the Extension. However, because Extension have no access to managed beans since they are not created yet, I conclude that is no possible solution to use an #Observes AfterBeanDiscovery to modify the bean data. Even the BeanManager that gets passed in cannot find any of the beans.