Cannot query fromSql method with Entity Framework Core - visual-studio-2017

I started a asp.net core project, using EF core 2.0.1.
I was able to migrate a database successfully to the project and generated partial class as follows
public partial class ManagementContext : DbContext
{
public virtual DbSet<Result> Results { get; set; }
}
I'm able to connect to the database and get db and get the all records in the db by assigning:
var results = dbContext.Results.ToList();
However when trying to assign by .fromSql() method i get error:
invalidlidOperationException: 'The required column 'Id' was not present in the results of a 'FromSql' operation.'
The errors is received in both of the following queries (get_results is a stored procedure that returns records of Result:
var resultsThroughRawQuery = dbContext.Results.FromSql("select * from dbo.Results").ToList();
var resultsThroughStoredProcedure = dbContext.Results.FromSql("EXEC get_results").ToList();
Result indeed has an Id columnm which is the key.
Is there something I miss here?

Related

Mocking EF core computed field in InMemoryDatabase for unit tests

In my database I have computed field "FullName" created by EF core using HasComputedColumnSql fluent API and everything is working fine in the app.
However I have some unit tests using InMemory database which are testing some logic using "FullName" column which is null in InMemory database.
Any idea how I can mock computed column behavior in in memory database?
I’m using the following solution:
Add even handler for SavingChanges
Inside the handler, loop over entities of the type ou have a computed column on
Initialize computed value
Example:
Add event handler:
dbContext.SavingChanges += OnSaveChanges;
In my case, the class name is Ressource end computed property is “FullName” :
private void OnSaveChanges(object? sender, SavingChangesEventArgs e)
{
var dbContext = sender as <your context class>;
var ressources = dbContext.ChangeTracker.Entries().Where(x => x.Entity is Ressource).Select(x => x.Entity as Ressource).ToList();
foreach (var item in ressources)
item.FullName = item.FirstName + " " + item.LastName;
}
Hope it helps.

#SpringBootTest autowire repository cannot save data to real database

I try to make a unit test with real database (mean not in-memory database).
this is my config file:
#TestConfiguration
#EnableJpaAuditing
public class TestConfig {
#Bean
#Primary
public DataSource getDataSource() {
HikariDataSource hikariDataSource = new HikariDataSource();
hikariDataSource.setJdbcUrl("jdbc:mysql://localhost:3306/faptv");
hikariDataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
hikariDataSource.setUsername("mansion");
hikariDataSource.setPassword("mansion");
return hikariDataSource;
}
}
This is my sample test:
#RunWith(SpringRunner.class)
#SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
#AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
#ContextConfiguration(classes = {TestConfig.class})
#DirtiesContext
#Transactional
public class BaseEntityTest {
#Autowired
private TBL120Dao dao;
#Test
#Sql("classpath:/sql/abc.sql")
public void test() {
TBL120Dto dto = new TBL120Dto();
dto.setUserId("xxx");
dto.setUsername("ccsc");
dto.setPasswordHash("passss");
dao.save(dto);
assertThat(dao.findByUserId("kkk").isPresent()).isTrue();
}
}
This is my /sql/abc.sql
insert into tbl120(user_id, password_hash, username) value ("kkk", "ssss", "Ssss");
When the test is finished:
I see in my real database: it's has new row from sql.
But it don't have the row with userId 'xxx' from the test method. And, when I debug inside test method, It only exist once record of userId 'xxx' when I try to execute dao.findAll() (note that in real database not exist this, real database only exits data from sql), it can not access real database.
how can I save and select data from real database?
Spring transactional tests rollback automatically by default. See the documentation for how to customize this.

ASP.net core integration testing with inherited Startup class. Unable to locate View

I am attempting to write some integration tests against aspnet core 2.2. I want to use a TestStartup class that inherits from the normal Startup class to configure resources and services for testing purposes.
A simple example (can be found here: https://github.com/davidgouge/aspnet-integration-testing):
I have a solution that contains two projects:
IntegrationTestingWeb (a barebones aspnet mvc app)
IntegrationTestingTests (a testing project)
I have a test that uses the Web Startup class and asserts that OK is returned from /Home/Privacy
[Test]
public async Task GetPrivacy_Through_Normal_Startup()
{
var builder = new WebHostBuilder().UseStartup<Startup>();
var client = new TestServer(builder).CreateClient();
var result = await client.GetAsync("/Home/Privacy");
result.StatusCode.Should().Be(HttpStatusCode.OK);
}
This test passes.
If I create a TestStartupInTestProject class that inherites from Startup but place it in the Tests project, then I have to do some extra work when creating the WebHostBuilder but then the test fails.
[Test]
public async Task GetPrivacy_Through_Test_Startup_In_Test_Project()
{
var builder = new WebHostBuilder().ConfigureServices(services =>
{
var startupAssembly = typeof(TestStartupInTestProject).GetTypeInfo().Assembly;
var manager = new ApplicationPartManager();
manager.ApplicationParts.Add(new AssemblyPart(startupAssembly));
manager.ApplicationParts.Add(new AssemblyPart(typeof(HomeController).Assembly));
manager.FeatureProviders.Add(new ControllerFeatureProvider());
manager.FeatureProviders.Add(new ViewComponentFeatureProvider());
services.AddSingleton(manager);
}).UseStartup<TestStartupInTestProject>();
var client = new TestServer(builder).CreateClient();
var result = await client.GetAsync("/Home/Privacy");
result.StatusCode.Should().Be(HttpStatusCode.OK);
}
The error in the failure is:
Tests.Tests.GetPrivacy_Through_Test_Startup_In_Test_Project
System.InvalidOperationException : The view 'Privacy' was not found. The
following locations were searched:
/Views/Home/Privacy.cshtml
/Views/Shared/Privacy.cshtml
/Pages/Shared/Privacy.cshtml
So it looks like because my Startup class is located in the Test project, the views cannot be located. What setting am I missing to be able to find the Views?
It turns out I was missing .UseContentRoot(Directory.GetCurrentDirectory() + "\\..\\..\\..\\..\\IntegrationTestingWeb") when creating the WebHostBuilder. As it sounds, it sets the root dir where the app will look for Views etc.

Salesforce APEX Unit Test Error with REST Services / Error at SELECT of Case Object

I've succeeded to successfully construct a REST API using APEX language defined with an annotation: #RestResource.
I also wrote a matching Unit test procedure with #isTest annotation. The execution of the REST API triggered by a HTTP GET with two input parameters works well, while the Unit Test execution, returns a "null" value list resulting from the SOQL query shown below:
String mycase = inputs_case_number; // for ex. '00001026'
sObject[] sl2 = [SELECT Id, CaseNumber FROM Case WHERE CaseNumber = :mycase LIMIT 1];
The query returns:
VARIABLE_ASSIGNMENT [22]|sl2|[]|0x1ffefea6
I've also tried to execute it with a RunAs() method (see code below), using a dynamically created Salesforce test user, not anonymous, connected to a more powerful profile, but still receiving a "null" answer at the SOQL query. The new profile defines "View All" permission for Cases. Other SOQL queries to objects like: "User" and "UserRecordAccess" with very similar construction are working fine, both for REST APEX and Test APEX.
Is there a way to configure an access permission for Unit test (#isTest) to read the Case object and a few fields like: Id and CaseNumber. Is this error related to the "Tooling API" function and how can we fix this issue in the test procedure?
Code attachment: Unit Test Code
#isTest
private class MyRestResource1Test {
static testMethod void MyRestRequest() {
// generate temporary test user object and assign to running process
String uniqueUserName = 'standarduser' + DateTime.now().getTime() + '#testorg.com';
Profile p = [SELECT Id FROM Profile WHERE Name='StandardTestUser'];
User pu = new User(Alias='standt',Email='standarduser#testorg.com',LastName='testing',EmailEncodingKey='UTF-8',LanguageLocaleKey='en_US',LocaleSidKey='en_US',ProfileId=p.Id,TimeZoneSidKey='America/New_York',UserName=uniqueUserName);
System.RunAs(pu) {
RestRequest req = new RestRequest();
RestResponse res = new RestResponse();
req.requestURI = '/services/apexrest/sfcheckap/';
req.addParameter('useremail','testuserid#red.com');
req.addParameter('casenumber','00001026');
req.httpMethod = 'GET';
RestContext.request = req;
RestContext.response = res;
System.debug('Current User assigned is: ' + UserInfo.getUserName());
System.debug('Current Profile assigned is: ' + UserInfo.getProfileId());
Test.startTest();
Map<String, Boolean> resultMap = MyRestResource1.doGet();
Test.stopTest();
Boolean debugflag = resultMap.get('accessPermission');
String debugflagstr = String.valueOf(debugflag);
System.assert(debugflagstr.contains('true'));
}
}
}
Found a solution path by using: #isTest(SeeAllData=true)
See article: "Using the isTest(SeeAllData=true) Annotation"
https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_testing_seealldata_using.htm

SDN 2.1.0/neo4j 1.8: java.lang.IllegalArgumentException: Cannot obtain single field value for field 'schoolRef'

I am able add and save multiple SchoolRef, but am getting the error after retrieving the (ancestor and eagerly fetching the) Education object and then attempting to add another SchoolRef. This was working with SDN 2.0.1, but I've also changed other things, including the Repository/Cypher query below, so I can't isolate it to the upgrade.
#Fetch #RelatedTo(type = "EDUCATION_HAS_SCHOOLREF")
private Set<SchoolRef> schoolRefs = new HashSet<SchoolRef>();
public Education() {
}
public void addSchoolRef(SchoolRef schoolRef) {
getSchoolRefs().add(schoolRef);
}
Repository:
public interface UserRepository extends GraphRepository<User>, CypherDslRepository<User> {
#Query("start id=node:Identifier(identifier={0}) match id<-[:USER_HAS_IDENTIFIER]-user return user")
public User findById(String id);
Stacktrace:
Caused by: java.lang.IllegalArgumentException: Cannot obtain single field value for field 'schoolRef'
at org.springframework.data.neo4j.fieldaccess.RelatedToSingleFieldAccessorFactory$RelatedToSingleFieldAccessor.getValue(RelatedToSingleFieldAccessorFactory.java:94)
at org.springframework.data.neo4j.fieldaccess.DefaultEntityState.getValue(DefaultEntityState.java:97)
at org.springframework.data.neo4j.support.mapping.SourceStateTransmitter.copyEntityStatePropertyValue(SourceStateTransmitter.java:90)
at org.springframework.data.neo4j.support.mapping.SourceStateTransmitter.access$000(SourceStateTransmitter.java:40)
at org.springframework.data.neo4j.support.mapping.SourceStateTransmitter$2.doWithAssociation(SourceStateTransmitter.java:61)
at org.springframework.data.mapping.model.BasicPersistentEntity.doWithAssociations(BasicPersistentEntity.java:207)
at org.springframework.data.neo4j.support.mapping.SourceStateTransmitter.copyPropertiesFrom(SourceStateTransmitter.java:57)
at org.springframework.data.neo4j.support.mapping.Neo4jEntityConverterImpl.loadEntity(Neo4jEntityConverterImpl.java:100)
at org.springframework.data.neo4j.support.mapping.Neo4jEntityConverterImpl.read(Neo4jEntityConverterImpl.java:92)
at org.springframework.data.neo4j.support.mapping.Neo4jEntityPersister$CachedConverter.read(Neo4jEntityPersister.java:170)
at org.springframework.data.neo4j.support.mapping.Neo4jEntityPersister.createEntityFromState(Neo4jEntityPersister.java:189)
at org.springframework.data.neo4j.support.Neo4jTemplate.createEntityFromState(Neo4jTemplate.java:180)
at org.springframework.data.neo4j.fieldaccess.RelationshipHelper.createEntitySetFromRelationshipEndNodes(RelationshipHelper.java:130)
at org.springframework.data.neo4j.fieldaccess.RelatedToFieldAccessor.createEntitySetFromRelationshipEndNodes(RelatedToFieldAccessor.java:86)
at org.springframework.data.neo4j.fieldaccess.RelatedToSingleFieldAccessorFactory$RelatedToSingleFieldAccessor.getValue(RelatedToSingleFieldAccessorFactory.java:76)
at org.springframework.data.neo4j.fieldaccess.DefaultEntityState.getValue(DefaultEntityState.java:97)
at org.springframework.data.neo4j.support.mapping.SourceStateTransmitter.copyEntityStatePropertyValue(SourceStateTransmitter.java:90)
at org.springframework.data.neo4j.support.mapping.SourceStateTransmitter.access$000(SourceStateTransmitter.java:40)
at org.springframework.data.neo4j.support.mapping.SourceStateTransmitter$2.doWithAssociation(SourceStateTransmitter.java:61)
at org.springframework.data.mapping.model.BasicPersistentEntity.doWithAssociations(BasicPersistentEntity.java:207)
at org.springframework.data.neo4j.support.mapping.SourceStateTransmitter.copyPropertiesFrom(SourceStateTransmitter.java:57)
at org.springframework.data.neo4j.support.mapping.Neo4jEntityConverterImpl.loadEntity(Neo4jEntityConverterImpl.java:100)
at org.springframework.data.neo4j.support.mapping.Neo4jEntityConverterImpl.read(Neo4jEntityConverterImpl.java:92)
at org.springframework.data.neo4j.support.mapping.Neo4jEntityPersister$CachedConverter.read(Neo4jEntityPersister.java:170)
at org.springframework.data.neo4j.support.mapping.Neo4jEntityPersister.createEntityFromState(Neo4jEntityPersister.java:189)
at org.springframework.data.neo4j.support.mapping.Neo4jEntityPersister.persist(Neo4jEntityPersister.java:244)
at org.springframework.data.neo4j.support.mapping.Neo4jEntityPersister.persist(Neo4jEntityPersister.java:231)
at org.springframework.data.neo4j.support.Neo4jTemplate.save(Neo4jTemplate.java:293)
at org.springframework.data.neo4j.support.Neo4jTemplate.save(Neo4jTemplate.java:287)
at org.springframework.data.neo4j.fieldaccess.RelationshipHelper.getOrCreateState(RelationshipHelper.java:119)
at org.springframework.data.neo4j.fieldaccess.RelationshipHelper.createSetOfTargetNodes(RelationshipHelper.java:111)
at org.springframework.data.neo4j.fieldaccess.RelatedToFieldAccessor.createSetOfTargetNodes(RelatedToFieldAccessor.java:82)
at org.springframework.data.neo4j.fieldaccess.RelatedToCollectionFieldAccessorFactory$RelatedToCollectionFieldAccessor.setValue(RelatedToCollectionFieldAccessorFactory.java:66)
at org.springframework.data.neo4j.fieldaccess.ManagedFieldAccessorSet.updateValue(ManagedFieldAccessorSet.java:94)
at org.springframework.data.neo4j.fieldaccess.ManagedFieldAccessorSet.update(ManagedFieldAccessorSet.java:82)
at org.springframework.data.neo4j.fieldaccess.ManagedFieldAccessorSet.add(ManagedFieldAccessorSet.java:108)
---- Edit:
Same error, but under different circumstances..
School school = new School();
school = neo4j.repositoryFor(School.class).save(school);
User user1 = new User("Junit", "1");
SchoolRef schoolRef1 = new SchoolRef();
schoolRef1.setSchool(school);
user1.addSchoolRef(schoolRef1);
user1 = neo4j.repositoryFor(User.class).save(user1);
User user2 = new User("Junit", "2");
SchoolRef schoolRef2 = new SchoolRef();
schoolRef2.setSchool(school);
user2.addSchoolRef(schoolRef2);
user2 = neo4j.repositoryFor(User.class).save(user2); // <- error here
sometimes I can be blind to the obvious problem...
In my case, SchoolRef references a single school, but schools can have many schoolRefs. I had incorrectly implemented School with a single reference back to SchoolRef.
I was able to create multiple SchoolRefs which referenced a single School, but got this error when I tried to fetch a School which had the multiple references.
We ran into this issue as well, but it was due to having a separate relationship with the same label.