this URL shows how is used to be done:
http://zhangwenli.com/blog/2014/08/25/crosswalk-calling-java-methods-with-javascript/
However, the getSettings() function is now removed.
How does one now enable Javascript ?
public class MyActivity extends Activity {
private XWalkView xWalkWebView;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.my_activity_xml);
xWalkWebView = (XWalkView)findViewById(R.id.xwalkView);
xWalkWebView.addJavascriptInterface(new WebAppInterface(), "Android");
xWalkWebView.load(url_your_want_to_load,null);
}
public class WebAppInterface {
#org.xwalk.core.JavascriptInterface
public void callFunction(){
// Do your Android Stuff here
}
}
}
Now Call function in your page as:
Android.callFunction();
Related
I am new to TDD. Also new to MVP and Rxjava. I just dive into it and It is worth it. But I stuck at the testing part. I understand the basis of unit testing. It is a little bit difficult for me in beginning. But I stuck here and So how can test the presenter?
Here is the Presenter class -
public class NewsPresenter {
private final RxjavaService service;
private final MainView view;
private CompositeSubscription subscriptions;
public NewsPresenter(RxjavaService service, MainView view) {
this.service = service;
this.view = view;
subscriptions = new CompositeSubscription();
}
public void getNewsList(String urlQ){
view.showWait();
Subscription subscription = service.getNews(urlQ ,new RxjavaService.GetNewsCallback() {
#Override
public void onSuccess(Articles articles) {
view.removeWait();
view.getNewsListSuccess(articles);
}
#Override
public void onError(NetworkError networkError) {
view.removeWait();
view.onFailure(networkError.getAppErrorMessage());
Log.i("huh",networkError.getMessage());
}
});
subscriptions.add(subscription);
}
public void onStop(){
subscriptions.unsubscribe();
}
}
Here is the View Interface -
public interface MainView {
void showWait();
void removeWait();
void onFailure(String appErrorMessage);
void getNewsListSuccess(Articles articles);
}
Here is the RxJavaService class -
public class RxjavaService {
private final NewsRestService newsRestService;
public RxjavaService(NewsRestService newsRestService) {
this.newsRestService = newsRestService;
}
public interface GetNewsCallback {
void onSuccess(Articles articles);
void onError(NetworkError networkError);
}
public Subscription getNews(String q, final GetNewsCallback getNewsCallback) {
Log.i("stuck","service called");
return newsRestService.getNewsBySearch(q,"8dca7dea475e41e49518b2c61131e118",100)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.onErrorResumeNext(new Func1<Throwable, Observable<? extends Articles>>() {
#Override
public Observable<? extends Articles> call(Throwable throwable) {
return Observable.error(throwable);
}
})
.subscribe(new Subscriber<Articles>() {
#Override
public void onCompleted() {
Log.i("stuck","complete");
}
#Override
public void onError(Throwable e) {
getNewsCallback.onError(new NetworkError(e));
Log.i("stuck",e.getMessage());
}
#Override
public void onNext(Articles articles) {
getNewsCallback.onSuccess(articles);
Log.i("stuck","Onnext");
}
});
}
}
Here is the Test class where I am stuck-
#RunWith(MockitoJUnitRunner.class)
public class NewsListTest {
private NewsPresenter newsPresenter;
#Mock
private RxjavaService rxjavaService;
#Mock
private MainView mainView;
#Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
newsPresenter = new NewsPresenter(rxjavaService,mainView);
}
#After
public void tearDown() throws Exception {
mainView = null;
newsPresenter.onStop();
}
#Test
public void Testing_The_Result() {
}
}
First things first
If you're into TDD, you'd never get into the situation you described. In TDD you start with a failing test, and just then go write the implementation. So your question is much more about testing then TDD.
I would recommend switching to RxJava2, as RxJava1 reaches End Of Life on March 31.
Look strange to me that RxJavaService changes the API from publish/subscribe to callbacks. Why not stick with rx API all the way to presenter?
Test with mocked RxJavaService
If you'd like to finish writing the test with the setup you have in the test, it would look something like this:
#Test
public void Testing_The_Result() {
final RxjavaService.GetNewsCallback[] callback = new RxjavaService.GetNewsCallback[1];
Mockito.when(rxjavaService.getNews(ArgumentMatchers.anyString(), ArgumentMatchers.any(RxjavaService.GetNewsCallback.class))).thenAnswer(new Answer<Subscription>() {
public Subscription answer(InvocationOnMock invocationOnMock) {
callback[0] = invocationOnMock.getArgument(1);
return mock(Subscription.class);
}
});
newsPresenter.getNewsList("some url");
Articles articles = new Articles();
callback[0].onSuccess(articles);
verify(mainView).removeWait();
verify(mainView).getNewsListSuccess(articles);
}
You can get rid of the ugly code by not using Mockito to mock RxJavaService, but rather roll you own hand-written mock, which would store the callback and provide it to the test.
However, I'd recommend a different approach.
Test with real RxJavaService and mocked NewsRestService
I'd say it makes more sense and gives a better test if we mocked only the NewsRestService:
#RunWith(MockitoJUnitRunner.class)
public class NewsList2Test {
private NewsPresenter newsPresenter;
#Mock
private MainView mainView;
#Mock
private NewsRestService newsRestService;
#Before
public void setUp() {
newsPresenter = new NewsPresenter(new RxjavaService(newsRestService), mainView);
}
#Test
public void show_success_in_view_when_there_are_articles() {
when(newsRestService.getNewsBySearch(eq("some url"), anyString(), anyInt()))
.thenReturn(Observable.just(new Articles()));
newsPresenter.getNewsList("some url");
verify(mainView).removeWait();
verify(mainView).getNewsListSuccess(any(Articles.class));
}
}
Having some issues getting my repository to retrieve information - keeps coming back null. Any Thoughts would be appreciated - new to this and teaching myself.
Repository:
public class CustomerRepository : ICustomerRepository
{
private masterContext context;
public CustomerRepository(masterContext context)
{
this.context = context;
}
public IEnumerable<Customer> GetCustomers()
{
return context.Customer.ToList();
}
public Customer GetCustomerById(int customerId)
{
var result = (from c in context.Customer where c.CustomerId == customerId select c).FirstOrDefault();
return result;
}
public void Save()
{
context.SaveChanges();
}
Controller:
public class CustomerController : Controller
{
private readonly ICustomerRepository _repository = null;
public ActionResult Index()
{
var model = (List<Customer>)_repository.GetCustomers();
return View(model);
}
public ActionResult New()
{
return View();
}
}
MasterContext which i had efc make:
public partial class masterContext : DbContext
{
public masterContext(DbContextOptions<masterContext> options)
: base(options)
{ }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Customer>(entity =>
{
entity.Property(e => e.CustomerName).IsRequired();
});
}
public virtual DbSet<Customer> Customer { get; set; }
public virtual DbSet<Order> Order { get; set; }
}
I think you need to create instances of you Context and your Repository. So in your Controller you need to something like this:
private masterContext context = new masterContext();
private ICustomerRepository repository = new CustomerRepository(context);
I assume that you're not using Dependency injection ... if so you just need to create a Constructor for your Controller that takes CustomerRepository as argument:
public CustomerController(ICustomerRepository _repository) {
repository = _repository;
}
If you did not configure your database context, look here: https://docs.efproject.net/en/latest/platforms/aspnetcore/new-db.html
This will than enable you the dependency injection. Everything you than need to do for the Repository is to use
services.AddScoped<ICustomerRepository,
CustomerRepository>();
And I think it could be good to remove the ToList() in the Repository class and remove the Cast List<Customer> in your Controller and use ToList() instead, if it's really needed. Because if you're using it in the View the ienumerable could also work.
When running multiple [TestClass]es at the same time, why do the [ClassCleanup()] methods only get called at the very end?
File: UnitTest1.cs
[TestClass]
public class UnitTest1
{
[ClassInitialize()]
public static void ClassInit(TestContext context)
{
}
[ClassCleanup()]
public static void ClassCleanup()
{
}
[TestMethod]
public void TestMethod1()
{
}
}
File: UnitTest2.cs
[TestClass]
public class UnitTest2
{
[ClassInitialize()]
public static void ClassInit(TestContext context)
{
}
[ClassCleanup()]
public static void ClassCleanup()
{
}
[TestMethod]
public void TestMethod1()
{
}
}
The execution order is the following:
UnitTest2.ClassInit()
UnitTest2.TestMethod1()
UnitTest1.ClassInit()
UnitTest1.TestMethod1()
UnitTest2.ClassCleanup()
UnitTest1.ClassCleanup()
Notice that both [ClassCleanup] methods are executed at the end of the set; not after each TestClass is "done".
But I expected a different behavior:
UnitTest2.ClassInit()
UnitTest2.TestMethod1()
UnitTest2.ClassCleanup() - Expected
UnitTest1.ClassInit()
UnitTest1.TestMethod1()
UnitTest1.ClassCleanup() - Expected
Microsoft's Documentation - ClassCleanupAttribute Class says, "Identifies a method that contains code to be used after all the tests in the test class have run and to free resources obtained by the test class. "
But it appears to be run/executed late!
How do I fix this? Or find a way to execute a method from the same TestClass right before the next ClassInitialize method.
I have a simple Http module:
public class CustomLoggingModule : IHttpModule
{
public void Init(HttpApplication context)
{
context.BeginRequest += BeginRequest;
context.EndRequest += EndRequest;
}
public void BeginRequest(object sender, EventArgs eventArgs)
{
//some code
}
public void EndRequest(object sender, EventArgs eventArgs)
{
//some
}
public void Dispose()
{
}
}
How can I unit test this? Especially how is it possible to mock events? Can anyone give some simple example?
Not sure why you have decided to hardwire the dependencies as new LogService() and new HttpContextWrapper(HttpContext.Current) within the CustomLoggingModule. If want to test whether LogInfo() method is called or not, it becomes lot easier if you can externalize these dependencies so you can inject stubbed/mocked version etc.
Also your question does not state that you are using an IOC container. You can register the HttpModule with the container and provide external dependencies at runtime. Your question also does not state that using an isoloation/mock object framework.
Therefore I will provide you with a solution that you can verify whether LogInfo method is called, using hand written stubs and mocks.
To achieve this, we need to refactor CustomLoggingModule a bit, so it becomes more testable.
System Under Test (SUT)
public class CustomLoggingModule : IHttpModule
{
public ILogService LogService { get; set; }
public Func<ILoggingHttpContextWrapper> LogginHttpContextWrapperDelegate { get; set; }
public void Init(HttpApplication context) {
context.BeginRequest += BeginRequest;
context.EndRequest += EndRequest;
}
public CustomLoggingModule() {
LogginHttpContextWrapperDelegate = () => new LoggingHttpContextWrapper();
}
public void BeginRequest(object sender, EventArgs eventArgs) {
LogService.LogInfo(LogginHttpContextWrapperDelegate().HttpContextWrapper);
}
public void EndRequest(object sender, EventArgs eventArgs) {
//some
}
public void Dispose(){ }
}
As you see above, I have introduced 2 additional properties - ILogService so I can provide a Mocked verion and a delegate Func which allows me to stub the
new HttpContextWrapper(HttpContext.Current);
public interface ILoggingHttpContextWrapper {
HttpContextWrapper HttpContextWrapper { get; }
}
public class LoggingHttpContextWrapper : ILoggingHttpContextWrapper
{
public LoggingHttpContextWrapper() {
HttpContextWrapper = new HttpContextWrapper(HttpContext.Current);
}
public HttpContextWrapper HttpContextWrapper { get; private set; }
}
And then your real ILogService
public interface ILogService {
void LogInfo(HttpContextWrapper httpContextWrapper);
}
public class LogService : ILogService {
public void LogInfo(HttpContextWrapper httpContextWrapper)
{
//real logger implementation
}
}
Unit Test :
You would create a MockLoggerService, so you can verify the interaction i,e whether the LogInfo() method was called, etc. You also need a stubbed LoggingHttpContextWrapper to provide the fake HttpContextWrapper to the SUT (System Under Test)/ CustomLoggingModule.
public class StubLoggingHttpContextWrapper : ILoggingHttpContextWrapper
{
public StubLoggingHttpContextWrapper(){}
public HttpContextWrapper HttpContextWrapper { get; private set; }
}
public class MockLoggerService : ILogService
{
public bool LogInfoMethodIsCalled = false;
public void LogInfo(HttpContextWrapper httpContextWrapper) {
LogInfoMethodIsCalled = true;
}
}
MockLoggerService is very important. It is not the real logger service, but it is the mocked version. When we do public class MockLoggerService : ILogService this means that we are providing another layer of indirection to the logger service so we can verify the interaction of the behaviour.
You also notice that I have provided a boolean variable to verify whether the LogInfo method is called or not. This allows me to call this method from the SUT, and verify whether the method being called or not.
Now Your Unit Test can be implemented as below.
[TestMethod]
public void CustomLoggingModule_BeginRequest_VerifyLogInfoMethodIsCalled()
{
var sut = new CustomLoggingModule();
var loggerServiceMock = new MockLoggerService();
var loggingHttpContextWrapperStub = new StubLoggingHttpContextWrapper();
sut.LogService = loggerServiceMock;
sut.LogginHttpContextWrapperDelegate = () => loggingHttpContextWrapperStub;
sut.BeginRequest(new object(), new EventArgs());
Assert.IsTrue(loggerServiceMock.LogInfoMethodIsCalled);
}
I had the same issue with my custom http module and decided I won't give up that easily and will do all I can to trigger the BeginRequest event in unit test. I had to actually read through the source code of HttpApplication class and use reflection to invoke the method.
[TestMethod]
public void EventTriggered_DoesNotError()
{
using (var application = new HttpApplication())
{
var module = new CustomLoggingModule();
module.Init(application);
FireHttpApplicationEvent(application, "EventBeginRequest", this, EventArgs.Empty);
}
}
private static void FireHttpApplicationEvent(object onMe, string invokeMe, params object[] args)
{
var objectType = onMe.GetType();
object eventIndex = (object)objectType.GetField(invokeMe, System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic).GetValue(onMe);
EventHandlerList events = (EventHandlerList)objectType.GetField("_events", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic).GetValue(onMe);
EventHandler handler = (EventHandler)events[eventIndex];
Delegate[] delegates = handler.GetInvocationList();
foreach (Delegate dlg in delegates)
{
dlg.Method.Invoke(dlg.Target, args);
}
}
I am setting up some MSTest based unit tests. To make my life easier I want to use a base class that handles the generic setup and taredown all of my tests require. My base class looks like this:
[TestClass]
public class DBTestBase {
public TestContext TestContext { get; set; }
[ClassInitialize()]
public static void MyClassInitialize(TestContext testContext) {
var config = new XmlConfigurationSource("ARconfig_test.xml");
ActiveRecordStarter.Initialize(Assembly.Load("LocalModels"), config);
}
[TestInitialize()]
public void MyTestInitialize() {
ActiveRecordStarter.CreateSchema();
Before_each_test();
}
protected virtual void Before_each_test() { }
[TestCleanup()]
public void MyTestCleanup() {
After_each_test();
}
protected virtual void After_each_test() { }
}
My actual test class looks like this:
[TestClass]
public class question_tests : DBTestBase {
private void CreateInitialData() {
var question = new Question()
{
Name = "Test Question",
Description = "This is a simple test question"
};
question.Create();
}
protected override void Before_each_test() {
base.Before_each_test();
CreateInitialData();
}
[TestMethod]
public void test_fetching() {
var q = Question.FindAll();
Assert.AreEqual("Test Question", q[0].Name, "Incorrect name.");
}
}
The TestInitialize function works as expected. But the ClassInitialize function never runs. It does run if I add the following to my child class:
[ClassInitialize()]
public static void t(TestContext testContext) {
MyClassInitialize(testContext);
}
Is it possible to get my base class initialize function to run without referencing it in my child class?
ClassInitialize method is executed if and only if the concerned "class" contains at least one TestMethod, and at least one TestMethod from the class is selected for execution.
Confirm this was a problem for me too. I used a constructor on the base and a destructor for the cleanup
[TestClass]
public class question_tests : DBTestBase {
...
[TestCleanup()]
public void TestCleanup()
{
base.MyTestCleanup();
}