英文:
Junit test failing for the Observable pattern
问题
我在一个使用可观察模式的小程序中工作。下面是我无法修改的代码。
以下是你可以修改的类:
然而,我未能通过以下所有测试:
问题是股价增加没有在代码中反映出来。有人可以帮我找出问题在哪里吗?
英文:
I work in a small program using the Observable pattern. The code that I can't modify is provided below.
public abstract class ObservableStock {
private double price;
private StockType name;
public ObservableStock(StockType name) {
this.name = name;
}
protected ObservableStock() {
}
public StockType getName() {
return name;
}
public void setPrice(double price) {
this.price = price;
}
public abstract void notifyPriceChange(double price);
public abstract void registerStockExchangeCenter(ObserverStockExchangeCenter oc);
}
public abstract class ObserverStockExchangeCenter {
protected Map<StockType, Double> ownedStock;
public ObserverStockExchangeCenter() {
this.ownedStock = new HashMap<>();
}
public void buyStock(ObservableStock s) {
ownedStock.put(s.getName(), 0.0);
System.out.println("Helo");
}
//assume we won't change values in the map
public Map<StockType, Double> getOwnedStock() {
return ownedStock;
}
public abstract void observe(ObservableStock o);
public abstract void notifyChange(StockType type, double price);
}
public enum StockType {
Amazon,
Google,
}
I can modify the classes provided below:
public class ObservableStockImpl extends ObservableStock {
private ObserverStockExchangeCenter exchangeCenter;
public final StockType stockType;
public ObservableStockImpl(StockType name) {
this.stockType = name;
}
public void notifyPriceChange(double price) {
this.exchangeCenter.getOwnedStock().put(stockType, price);
this.exchangeCenter.notifyChange(stockType, price);
}
public void registerStockExchangeCenter(ObserverStockExchangeCenter oc) {
this.exchangeCenter = oc;
}
public StockType getStockType() {
return stockType;
}
}
public class ObserverStockExchangeCenterImpl extends ObserverStockExchangeCenter {
private final List<ObservableStockImpl> observableStocks;
public ObserverStockExchangeCenterImpl() {
super();
observableStocks = new ArrayList<>();
}
public void notifyChange(StockType type, double price) {
for (ObservableStockImpl os : observableStocks) {
if (os.getStockType().equals(type)) {
os.setPrice(price);
os.notifyPriceChange(price);
}
}
}
public void observe(ObservableStock o) {
observableStocks.add((ObservableStockImpl) o);
}
@Override
public void buyStock(ObservableStock s) {
ObservableStockImpl stock = (ObservableStockImpl) s;
ownedStock.put(stock.getStockType(), 0.0);
}
}
However, I failed to pass all the tests which are below:
@Test
public void stockPriceChangeTest(){
ObservableStock amazonStock = new ObservableStockImpl(StockType.Amazon);
ObserverStockExchangeCenter NYStockCenter = new ObserverStockExchangeCenterImpl();
NYStockCenter.buyStock(amazonStock);
Map<StockType, Double> boughtStocks = NYStockCenter.getOwnedStock();
assertEquals(1, boughtStocks.size());
assertEquals(0,boughtStocks.get(StockType.Amazon),0);
amazonStock.setPrice(5);
Map<StockType, Double> boughtStocks2 = NYStockCenter.getOwnedStock();
assertEquals(1, boughtStocks2.size());
// failing below
assertEquals(5,boughtStocks2.get(StockType.Amazon),0);
}
The issue is stock price increase not reflected in the code. Can anyone help me to find what is the issue here?
答案1
得分: 1
如我们在评论中讨论的那样,以下是更新后的工作代码。
问题:
- 你没有在
setPrice
中调用notifyPriceChange
exchangeCenter
在ObservableStockImpl
中没有被初始化/设置
额外反馈:
- 摆脱
ObservableStockImpl
类。尽管你正在“扩展”ObservableStock
,但实际上你在复制它。
在下面寻找以 // GT
开头的注释以查看我所做的更新:
package temp;
import org.junit.jupiter.api.Test;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class StockListenerTest {
@Test
public void stockPriceChangeTest() {
ObservableStock amazonStock = new ObservableStockImpl(StockType.Amazon);
ObserverStockExchangeCenter NYStockCenter = new ObserverStockExchangeCenterImpl();
amazonStock.registerStockExchangeCenter(NYStockCenter); // GT 1
NYStockCenter.buyStock(amazonStock);
Map<StockType, Double> boughtStocks = NYStockCenter.getOwnedStock();
assertEquals(1, boughtStocks.size());
assertEquals(0, boughtStocks.get(StockType.Amazon), 0);
amazonStock.setPrice(5);
Map<StockType, Double> boughtStocks2 = NYStockCenter.getOwnedStock();
assertEquals(1, boughtStocks2.size());
// 下面的测试失败了
assertEquals(5, boughtStocks2.get(StockType.Amazon), 0);
}
}
abstract class ObservableStock {
private double price;
private StockType name;
public ObservableStock(StockType name) {
this.name = name;
}
protected ObservableStock() {
}
public StockType getName() {
return name;
}
public void setPrice(double price) {
this.price = price;
notifyPriceChange(price); // GT 2 - 调用了 notifyPriceChange
}
public abstract void notifyPriceChange(double price);
public abstract void registerStockExchangeCenter(ObserverStockExchangeCenter oc);
}
abstract class ObserverStockExchangeCenter {
protected Map<StockType, Double> ownedStock;
public ObserverStockExchangeCenter() {
this.ownedStock = new HashMap<>();
}
public void buyStock(ObservableStock s) {
ownedStock.put(s.getName(), 0.0);
}
// 假设我们不会在映射中更改值
public Map<StockType, Double> getOwnedStock() {
return ownedStock;
}
public abstract void observe(ObservableStock o);
public abstract void notifyChange(StockType type, double price);
}
enum StockType {
Amazon,
Google,
}
class ObservableStockImpl extends ObservableStock {
private ObserverStockExchangeCenter exchangeCenter;
public final StockType stockType;
public ObservableStockImpl(StockType name ) {
this.stockType = name;
}
public void notifyPriceChange(double price) {
this.exchangeCenter.getOwnedStock().put(stockType, price);
this.exchangeCenter.notifyChange(stockType, price);
}
public void registerStockExchangeCenter(ObserverStockExchangeCenter oc) {
this.exchangeCenter = oc;
}
public StockType getStockType() {
return stockType;
}
}
class ObserverStockExchangeCenterImpl extends ObserverStockExchangeCenter {
private final List<ObservableStockImpl> observableStocks;
public ObserverStockExchangeCenterImpl() {
super();
observableStocks = new ArrayList<>();
}
public void notifyChange(StockType type, double price) {
for (ObservableStockImpl os : observableStocks) {
if (os.getStockType().equals(type)) {
os.setPrice(price);
os.notifyPriceChange(price);
}
}
}
public void observe(ObservableStock o) {
observableStocks.add((ObservableStockImpl) o);
}
@Override
public void buyStock(ObservableStock s) {
ObservableStockImpl stock = (ObservableStockImpl) s;
ownedStock.put(stock.getStockType(), 0.0);
}
}
如果需要进一步帮助,请随时提问。
英文:
As we discussed on the comments, here's the working code after the updates.
Problems:
- you were not calling
notifyPriceChange
atsetPrice
exchangeCenter
was not initialized/set at ObservableStockImpl
BONUS Feedback:
- get rid of
ObservableStockImpl
class. You are actually duplicating though you are "extending"ObservableStock
Look for comments starting with // GT
below for the updates i made:
package temp;
import org.junit.jupiter.api.Test;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class StockListenerTest {
@Test
public void stockPriceChangeTest() {
ObservableStock amazonStock = new ObservableStockImpl(StockType.Amazon);
ObserverStockExchangeCenter NYStockCenter = new ObserverStockExchangeCenterImpl();
amazonStock.registerStockExchangeCenter(NYStockCenter); // GT 1
NYStockCenter.buyStock(amazonStock);
Map<StockType, Double> boughtStocks = NYStockCenter.getOwnedStock();
assertEquals(1, boughtStocks.size());
assertEquals(0, boughtStocks.get(StockType.Amazon), 0);
amazonStock.setPrice(5);
Map<StockType, Double> boughtStocks2 = NYStockCenter.getOwnedStock();
assertEquals(1, boughtStocks2.size());
// failing below
assertEquals(5, boughtStocks2.get(StockType.Amazon), 0);
}
}
abstract class ObservableStock {
private double price;
private StockType name;
public ObservableStock(StockType name) {
this.name = name;
}
protected ObservableStock() {
}
public StockType getName() {
return name;
}
public void setPrice(double price) {
this.price = price;
notifyPriceChange(price); //GT 2 - called notifyPriceChange
}
public abstract void notifyPriceChange(double price);
public abstract void registerStockExchangeCenter(ObserverStockExchangeCenter oc);
}
abstract class ObserverStockExchangeCenter {
protected Map<StockType, Double> ownedStock;
public ObserverStockExchangeCenter() {
this.ownedStock = new HashMap<>();
}
public void buyStock(ObservableStock s) {
ownedStock.put(s.getName(), 0.0);
}
//assume we won't change values in the map
public Map<StockType, Double> getOwnedStock() {
return ownedStock;
}
public abstract void observe(ObservableStock o);
public abstract void notifyChange(StockType type, double price);
}
enum StockType {
Amazon,
Google,
}
class ObservableStockImpl extends ObservableStock {
private ObserverStockExchangeCenter exchangeCenter;
public final StockType stockType;
public ObservableStockImpl(StockType name ) {
this.stockType = name;
}
public void notifyPriceChange(double price) {
this.exchangeCenter.getOwnedStock().put(stockType, price);
this.exchangeCenter.notifyChange(stockType, price);
}
public void registerStockExchangeCenter(ObserverStockExchangeCenter oc) {
this.exchangeCenter = oc;
}
public StockType getStockType() {
return stockType;
}
}
class ObserverStockExchangeCenterImpl extends ObserverStockExchangeCenter {
private final List<ObservableStockImpl> observableStocks;
public ObserverStockExchangeCenterImpl() {
super();
observableStocks = new ArrayList<>();
}
public void notifyChange(StockType type, double price) {
for (ObservableStockImpl os : observableStocks) {
if (os.getStockType().equals(type)) {
os.setPrice(price);
os.notifyPriceChange(price);
}
}
}
public void observe(ObservableStock o) {
observableStocks.add((ObservableStockImpl) o);
}
@Override
public void buyStock(ObservableStock s) {
ObservableStockImpl stock = (ObservableStockImpl) s;
ownedStock.put(stock.getStockType(), 0.0);
}
}
答案2
得分: 0
前面的答案是正确的,但是他修改了测试方法,这是不允许的。我已经完成了,没有任何测试方法修改,只进行了轻微的更改。
关键在于这个重写的方法,在这个方法中,我们使用 super 关键字将注册到交易所的操作完成,然后回到父方法:
@Override
public void buyStock(ObservableStock observableStock) {
observableStock.registerStockExchangeCenter(this);
super.buyStock(observableStock);
}
ObservableStockImpl 类示例:
class ObservableStockImpl extends ObservableStock {
private ObserverStockExchangeCenter exchangeCenter;
public final StockType stockType;
public ObservableStockImpl(StockType name) {
super(name);
this.stockType = name;
this.exchangeCenter = new ObserverStockExchangeCenterImpl();
}
public void notifyPriceChange(double price) {
this.exchangeCenter.getOwnedStock().put(stockType, price);
}
public void registerStockExchangeCenter(ObserverStockExchangeCenter oc) {
this.exchangeCenter = oc;
}
@Override
public void setPrice(double price) {
notifyPriceChange(price);
}
}
ObserverStockExchangeCenterImpl 类示例:
class ObserverStockExchangeCenterImpl extends ObserverStockExchangeCenter {
private final List<ObservableStock> observableStocks;
public ObserverStockExchangeCenterImpl() {
super();
observableStocks = new ArrayList<>();
}
public void notifyChange(StockType type, double price) {
for (ObservableStock observableStock : observableStocks) {
if (observableStock == null) {
continue;
}
if (observableStock.getName().equals(type)) {
observableStock.notifyPriceChange(price);
}
}
}
public void observe(ObservableStock o) {
observableStocks.add(o);
}
@Override
public void buyStock(ObservableStock observableStock) {
observableStock.registerStockExchangeCenter(this);
super.buyStock(observableStock);
}
}
英文:
The previous answer is correct but, he modified the test method which is not allowed. I have done with w/o any test method modification with slight changes.
The trick is in this overridden method where we register to the exchange and then move back to the mother method using the super keyword:
@Override
public void buyStock(ObservableStock observableStock) {
observableStock.registerStockExchangeCenter(this);
super.buyStock(observableStock);
}
class ObservableStockImpl extends ObservableStock {
private ObserverStockExchangeCenter exchangeCenter;
public final StockType stockType;
public ObservableStockImpl(StockType name) {
super(name);
this.stockType = name;
this.exchangeCenter = new ObserverStockExchangeCenterImpl();
}
public void notifyPriceChange(double price) {
this.exchangeCenter.getOwnedStock().put(stockType, price);
}
public void registerStockExchangeCenter(ObserverStockExchangeCenter oc) {
this.exchangeCenter = oc;
}
@Override
public void setPrice(double price) {
notifyPriceChange(price);
}
}
class ObserverStockExchangeCenterImpl extends ObserverStockExchangeCenter {
private final List<ObservableStock> observableStocks;
public ObserverStockExchangeCenterImpl() {
super();
observableStocks = new ArrayList<>();
}
public void notifyChange(StockType type, double price) {
for (ObservableStock observableStock : observableStocks) {
if (observableStock == null) {
continue;
}
if (observableStock.getName().equals(type)) {
observableStock.notifyPriceChange(price);
}
}
}
public void observe(ObservableStock o) {
observableStocks.add(o);
}
@Override
public void buyStock(ObservableStock observableStock) {
observableStock.registerStockExchangeCenter(this);
super.buyStock(observableStock);
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论