I am trying to mock function that returns structure. But I get below problem
==> error: use of deleted function
class MockTest: public TestInterface
{
MOCK_METHOD1(func1, struct Response(std::string const &serviceName));
};
TEST_F (Test_1, Start)
{
struct Response Obj;
Obj.var = 5;
EXPECT_CALL(*Mockpointer, func1(_))
.Times(1)
.WillOnce(Return(Obj)); /*Compiler throws error here [error: use of deleted function]*/
auto result = FileToTest_Obj->start(); /*please Assume start function is under test*/
EXPECT_EQ(true, result);
}
Code snippet for reference.
bool start()
{
struct Response response = func1(serviceName);
if(5 == response.var ) {
return true;
}
return false;
}
Is there something I am missing. Is there any sample examples I can refer to mock the function that returns structure
Related
I'm building a weather app for practice and I'm getting following error:
Class 'Future<dynamic>' has no instance method '[]'.
Receiver: Instance of 'Future<dynamic>'
Tried calling: []("weather")
And this is where I think it comes from:
void updateUI(dynamic weatherData) {
var condition = weatherData['weather'][0]['id'];
String cityName = weatherData['name'];
double temp = weatherData['main']['temp'];
temperature = temp.toInt();
}
Had to create a class for my Data i got from my api call:
class WeatherData {
final int conditionID;
final String cityName;
final double temperature;
const WeatherData({
required this.conditionID,
required this.cityName,
required this.temperature,
});
factory WeatherData.fromJson(Map<String, dynamic> json) {
return WeatherData(
conditionID: json['weather'][0]['id'],
cityName: json['name'],
temperature: json['main']['temp'],
);
}
}
And then use it in updateUI() like this:
void updateUI(WeatherData weatherData) {
var condition = weatherData.conditionID;
String cityName = weatherData.cityName;
double temp = weatherData.temperature;
temperature = temp.toInt();
}
As always the documentation helped me a lot:
https://docs.flutter.dev/cookbook/networking/fetch-data
I recently started learning Unit Testing and now have the requirement write unit tests using Xunit and Moq for dot net core application.
I can write some very basic but when it comes to write them for complex classes , I am kind of stuck.
Below is the class I will be writing tests for.
public class AgeCategoryRequestHandler : IInventoryRequestHandler<InventoryRequest, HandlerResult>
{
private readonly IRepositoryResolver _repositoryResolver;
Hotels.HBSI.Logging.ILogger logger;
public AgeCategoryRequestHandler(IRepositoryResolver repositoryResolver, Hotels.HBSI.Logging.ILogger iLogger)
{
_repositoryResolver = repositoryResolver;
logger = iLogger;
}
public async Task<HandlerResult> Run(InventoryRequest inventoryRequest)
{
var result = await ProcessRequest(inventoryRequest);
return CreateResponse(inventoryRequest, result);
}
private async Task<int> ProcessRequest(InventoryRequest inventoryRequest)
{
logger.Info("AgeCategory requesthandler processrequest start");
var repository = _repositoryResolver.ResolveEstabAgeCategory();
if (repository is not null)
{
return await repository.InsertUpdateEstabAgeCategoryDetail(inventoryRequest.EstabAgeCategories)
.ConfigureAwait(false);
}
logger.Info("AgeCategory requesthandler processrequest complete");
return InernalError.reponotfound;
}
public HandlerResult CreateResponse(InventoryRequest inventoryRequest, int resultCount)
{
var requestCount = inventoryRequest.EstabAgeCategories.Count;
var handlerResult = new HandlerResult() { Id = RequestHandlerEnum.AgeCategrory.ToInt() };
if (requestCount > 0 && resultCount < requestCount)
{
handlerResult.IsSuccess = false;
handlerResult.ErrorCode = OTAErrorType.InvalidAgeCategory.ToInt();
}
else if (requestCount > 0 || requestCount == resultCount)
{
handlerResult.IsSuccess = true;
handlerResult.ErrorCode = 0;
}
return handlerResult;
}
}
Just to start , IRepositoryResolver and ILogger are in the constructor so I have created mock for these but unable to go beyond that as I am still in initial phase of learning.
Could someone explain me the steps/approach to accomplish this?.
Edit : What I have done so far is below ( can't figure out what are the things to be done and where to start or write )
Edit 2 : Did some more modifications to my test code , can someone comment if I am in right direction ? what else can I test ?
public class AgeCategoryRequestHandlerTest
{
private AgeCategoryRequestHandler _ageCategoryRequestHandler;
private readonly Mock<AgeCategoryRequestHandler> _ageCategory = new Mock<AgeCategoryRequestHandler>();
private readonly Mock<Hotels.HBSI.Logging.ILogger> _mockLogger = new Mock<Hotels.HBSI.Logging.ILogger>();
private readonly Mock<IRepositoryResolver> _mockRepositoryResolver = new Mock<IRepositoryResolver>();
public AgeCategoryRequestHandlerTest()
{
_ageCategoryRequestHandler = new AgeCategoryRequestHandler(_mockRepositoryResolver.Object, _mockLogger.Object);
}
[Fact]
public async void Testtt()
{
var fixture = new Fixture();
var inventory = fixture.Create<InventoryRequest>();
var hndlr = fixture.Create<HandlerResult>();
hndlr.ErrorCode = 0;
int resultCount = 3;
await _ageCategoryRequestHandler.Run(inventory);
HandlerResult response = _ageCategoryRequestHandler.CreateResponse(inventory, resultCount);
Assert.Equal(hndlr.ErrorCode, response.ErrorCode);
}
Tried running Chris B suggested code , was getting type conversion error EstabAgeCategories = new List<int>
Now I have used fixture for creating automatic objects and did some assert values. Below is the code sample
var fixture = new Fixture();
var inventoryRequest = fixture.Create<InventoryRequest>();
_mockRepository
.Setup(x => x.InsertUpdateEstabAgeCategoryDetail(inventoryRequest.EstabAgeCategories))
.ReturnsAsync(6);
_mockRepositoryResolver
.Setup(x => x.ResolveEstabAgeCategory())
.Returns(_mockRepository.Object);
// act
var result = await _ageCategoryRequestHandler.Run(inventoryRequest);
// assert
_mockRepository
.Verify(x => x.InsertUpdateEstabAgeCategoryDetail(inventoryRequest.EstabAgeCategories), Times.Once);
Assert.True(result.Id == 6);
Assert.True(result.ErrorCode == 0);
Assert.True(result.IsSuccess);
From the unit test code you've posted, it looks like you are getting confused on what to test.
Look at your class and identify your "public" interface i.e. what methods can be called from other parts of your code. You should really only test public methods. Private methods are usually tested via public methods.
Looking at AgeCategoryRequestHandler, you have two public methods - Run and CreateResponse. I would question whether CreateResponse needs to be public but we'll leave it for now. For each of these methods, you want to be asserting that the returned value is what you expect given the input value.
private AgeCategoryRequestHandler _ageCategoryRequestHandler;
// Not needed
private readonly Mock<AgeCategoryRequestHandler> _ageCategory = new Mock<AgeCategoryRequestHandler>();
private readonly Mock<Hotels.HBSI.Logging.ILogger> _mockLogger = new Mock<Hotels.HBSI.Logging.ILogger>();
private readonly Mock<IRepositoryResolver> _mockRepositoryResolver = new Mock<IRepositoryResolver>();
public AgeCategoryRequestHandlerTest()
{
_ageCategoryRequestHandler = new AgeCategoryRequestHandler(_mockRepositoryResolver.Object, _mockLogger.Object);
}
The set up of the unit test is going the right way - you have created mocks for your dependencies but I see you have created a mock for the class you are trying to test - this is not needed and can be removed. You want to be testing the actual class itself which you are initializing in the constructor.
public async Task<HandlerResult> Run(InventoryRequest inventoryRequest)
{
var result = await ProcessRequest(inventoryRequest);
return CreateResponse(inventoryRequest, result);
}
private async Task<int> ProcessRequest(InventoryRequest inventoryRequest)
{
_logger.LogInformation("AgeCategory requesthandler processrequest start");
var repository = _repositoryResolver.ResolveEstabAgeCategory();
if (repository != null)
{
return await repository.InsertUpdateEstabAgeCategoryDetail(inventoryRequest.EstabAgeCategories).ConfigureAwait(false);
}
_logger.LogInformation("AgeCategory requesthandler processrequest complete");
return 0;
}
We can test the public Run method by looking at the method and seeing what it is going to do when executed. Firstly, it's going to call a private method ProcessRequest. Inside ProcessRequest, the IRepositoryResolver dependency is going to be used. This means we need to "set up" this dependency in our unit test to satisfy the if (repository != null) condition.
I assume the IRepositoryResolver returns another interface (?) - something like:
public interface IRepository
{
Task<int> InsertUpdateEstabAgeCategoryDetail(List<int> x);
}
So in your unit test, you need to create a mock for the repository being returned from IRepositoryResolver:
private readonly Mock<IRepository> _mockRepository = new Mock<IRepository>();
Then, you need to set up the mock IRepositoryResolver to return the mock repository above:
_mockRepositoryResolver
.Setup(x => x.ResolveEstabAgeCategory())
.Returns(_mockRepository.Object);
This is to satisfy the if (repository != null) condition.
_mockRepository
.Setup(x => x.InsertUpdateEstabAgeCategoryDetail(inventoryRequest.EstabAgeCategories))
.ReturnsAsync(6);
Next, you need to set up the InsertUpdateEstabAgeCategoryDetail() method on the mock repository to return a value. This value is being returned by ProcessRequest() and then used to call CreateResponse(inventoryRequest, result) as the result parameter.
if (requestCount > 0 && resultCount < requestCount)
{
handlerResult.IsSuccess = false;
handlerResult.ErrorCode = (int)OTAErrorType.InvalidAgeCategory;
}
else if (requestCount > 0 || requestCount == resultCount)
{
handlerResult.IsSuccess = true;
handlerResult.ErrorCode = 0;
}
Now you can look at the CreateResponse method and by setting different values for inventoryRequest.EstabAgeCategories and setting up the mock _mockRepository.Setup(x => x.InsertUpdateEstabAgeCategoryDetail(inventoryRequest.EstabAgeCategories)).ReturnsAsync(6); to return different values, you can satisfy the different paths through the if statement.
CreateResponse is returning an instance of HandlerResult which in turn is being returned by Task<HandlerResult> Run. This is the returned object you want to make assertions on.
One of the unit test cases might look like this (I have not tested it myself):
[Fact]
public async Task GivenInventoryRequest_WhenRun_ThenHandlerResultReturned()
{
// arrange
var inventoryRequest = new InventoryRequest
{
EstabAgeCategories = new List<int>
{
1, 2, 3, 4, 5
}
};
_mockRepository
.Setup(x => x.InsertUpdateEstabAgeCategoryDetail(inventoryRequest.EstabAgeCategories))
.ReturnsAsync(6);
_mockRepositoryResolver
.Setup(x => x.ResolveEstabAgeCategory())
.Returns(_mockRepository.Object);
// act
var result = await _ageCategoryRequestHandler.Run(inventoryRequest);
// assert
_mockRepository
.Verify(x => x.InsertUpdateEstabAgeCategoryDetail(inventoryRequest.EstabAgeCategories), Times.Once);
Assert.True(result.Id == 0);
Assert.True(result.ErrorCode == 0);
Assert.False(result.IsSuccess);
}
I have a Nancy module which uses a function which expects as parameters a string (a captured pattern from a route) and a method group. When trying to pass the parameter directly it will not compile as I "cannot use a method group as an argument to a dynamically dispatched operation".
I have created a second route which attempts to cast the dynamic to a string, but this always returns null.
using System;
using Nancy;
public class MyModule : NancyModule
{
public MyModule()
{
//Get["/path/{Name}/action"] = parameters =>
// {
// return MyMethod(parameters.Name, methodToBeCalled); // this does not compile
// };
Get["/path/{Name}/anotherAction"] = parameters =>
{
return MyMethod(parameters.Name as string, anotherMethodToBeCalled);
};
}
public Response MyMethod(string name, Func<int> doSomething)
{
doSomething();
return Response.AsText(string.Format("Hello {0}", name));
}
public int methodToBeCalled()
{
return -1;
}
public int anotherMethodToBeCalled()
{
return 1;
}
}
Tested with the following class in a separate project:
using System;
using Nancy;
using Nancy.Testing;
using NUnit.Framework;
[TestFixture]
public class MyModuleTest
{
Browser browser;
[SetUp]
public void SetUp()
{
browser = new Browser(with =>
{
with.Module<MyModule>();
with.EnableAutoRegistration();
});
}
[Test]
public void Can_Get_View()
{
// When
var result = browser.Get("/path/foobar/anotherAction", with => with.HttpRequest());
// Then
Assert.AreEqual(HttpStatusCode.OK, result.StatusCode);
Assert.AreEqual("Hello foobar", result.Body.AsString()); //fails as parameters.Name is always null when cast to a string
}
}
You can find the whole test over on github
I've had similar issues when using 'as' so I tend to use explicitly cast it:
return MyMethod((string)parameters.Name, anotherMethodToBeCalled);
Also I think there was a bug raised with the casing on parameters, but I think it's better to keep them lowercase:
Get["/path/{name}/anotherAction"]
(string)parameters.name
Your code works for me with upper case and lowercase, using the explicit cast.
I have the following PHP code;
<?php
component_customer_init();
component_customer_go();
function component_customer_init()
{
$customer = Customer::getInstance();
$customer->set(1);
}
function component_customer_go()
{
$customer = Customer::getInstance();
$customer->get();
}
class Customer
{
public $id;
static $class = false;
static function getInstance()
{
if(self::$class == false)
{
self::$class = new Customer;
}
else
{
return self::$class;
}
}
public function set($id)
{
$this->id = $id;
}
public function get()
{
print $this->id;
}
}
?>
I get the following error;
Fatal error: Call to a member function set() on a non-object in /.../classes/customer.php on line 9
Can anyone tell me why I get this error? I know this code might look strange, but it's based on a component system that I'm writing for a CMS. The aim is to be able to replace HTML tags in the template e.g.;
<!-- component:customer-login -->
with;
<?php component_customer_login(); ?>
I also need to call pre-render methods of the "Customer" class to validate forms before output is made etc.
If anyone can think of a better way, please let me know but in the first instance, I'd like to know why I get the "Fatal error" mentioned above.
Well, I think your Customer::getInstance() method is flawed. It should look like this:
...
static function getInstance()
{
if(self::$class == false)
{
self::$class = new Customer;
return self::$class; // ADDED!!
}
else
{
return self::$class;
}
}
....
In the if(self::$class == false) branch you are creating the instance of the class, but you dont return it.
You could also rewrite it as such:
static function getInstance()
{
if(self::$class == false)
{
self::$class = new Customer;
}
return self::$class;
}
To make it a bit shorter.
DRY: Don't Repeat Yourself
static function getInstance()
{
if(self::$class == false)
{
self::$class = new Customer;
}
return self::$class;
}
And for Sinlgetons it is also important to prevent __clone() from being used. Making it private should solve that problem:
private function __clone() {}
I have an array of function callbacks, like this:
class Blah {
private var callbacks : Array;
private var local : Number;
public function Blah() {
local = 42;
callbacks = [f1, f2, f3];
}
public function doIt() : Void {
callbacks[0]();
}
private function f1() : Void {
trace("local=" + local);
}
private function f2() : Void {}
private function f3() : Void {}
}
If I run this code, I get "local=undefined" instead of "local=42":
blah = new Blah();
blah.doIt();
So, Flash function pointers don't carry context. What's the best way to solve this problem?
Try:
callbacks[0].apply(this, arguments array)
or
callbacks[0].call(this, comma-separated arguments)
If you want to "carry context" try :
public function doIt() : Void {
var f1() : function (): Void {
trace("local=" + local);
}
f1();
}
This creates a closure on this.local as expected
the most easy way is to use the Delegate class ... it works using the techniques Vlagged described ... although i must amend, that i do not understand the code at all (it is also syntactically incorrect) ...
otherwise, try this:
class AutoBind {
/**
* shortcut for multiple bindings
* #param theClass
* #param methods
* #return
*/
public static function methods(theClass:Function, methods:Array):Boolean {
var ret:Boolean = true;
for (var i:Number = 0; i < methods.length; i++) {
ret = ret && AutoBind.method(theClass, methods[i]);
}
return ret;
}
/**
* will cause that the method of name methodName is automatically bound to the owning instances of type theClass. returns success of the operation
* #param theClass
* #param methodName
* #return
*/
public static function method(theClass:Function, methodName:String):Boolean {
var old:Function = theClass.prototype[methodName];
if (old == undefined) return false;
theClass.prototype.addProperty(methodName, function ():Function {
var self:Object = this;
var f:Function = function () {
old.apply(self, arguments);
}
this[methodName] = f;
return f;
}, null);
return true;
}
}
and add this as the very last declaration in Blah:
private static var __init = AutoBind.methods(Blah, "f1,f2,f3".split(","));
that'll do the trick ... note that calls to f1, f2 and f3 will become slower though, because they need one extra function call ...
greetz
back2dos