繁体   English   中英

可观察模式的 Junit 测试失败

[英]Junit test failing for the Observable pattern

我在一个使用 Observable 模式的小程序中工作。 下面提供了我无法修改的代码。

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,
}

我可以修改下面提供的类:

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);
    }
}

但是,我未能通过以下所有测试:

@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);
}

问题是股票价格上涨没有反映在代码中。 任何人都可以帮我找到这里的问题吗?

正如我们在评论中所讨论的,这是更新后的工作代码。

问题:

  • 你没有在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());

        // 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);
    }
}

之前的答案是正确的,但他修改了不允许的测试方法。 我已经完成了没有任何测试方法修改的轻微更改。

诀窍是在这个重写的方法中,我们注册到交换,然后使用 super 关键字移回母方法:

@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);
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM